Подтвердить что ты не робот

Какие факторы делают PHP Unicode несовместимым?

Я могу использовать символы UTF-8 в моих скриптах.

На самом деле возможно иметь имена переменных и функций, содержащие символы Unicode.

Существует также расширение mb_string, которое касается многобайтных строк, но в бесчисленных статьях PHP критикует за отсутствие поддержки Unicode.

Я не понимаю; почему PHP не поддерживает Unicode?

4b9b3361

Ответ 1

Когда PHP был запущен несколько лет назад, UTF-8 не поддерживался. Мы говорим о времени, когда не-Unicode OS, как Windows 98/Me, все еще актуальна, и когда другие большие языки, такие как Delphi, также не являются Unicode. Не все языки были разработаны с учетом Unicode с первого дня, и полностью изменить язык на Unicode, не нарушая многого, сложно. Например, Delphi стал Unicode совместимым год или два назад, в то время как другие языки, такие как Java или С#, были разработаны в Юникоде с первого дня.

Итак, когда PHP рос и стал PHP 3, PHP 4 и теперь PHP 5, просто никто не решил добавить Unicode. Зачем? Предположительно, чтобы поддерживать совместимость с существующими сценариями или потому, что utf8_de/encode и mb_string уже существуют и работают. Я не знаю точно, но я твердо верю, что это как-то связано с органическим ростом. Возможности не просто существуют по умолчанию, они должны быть написаны кем-то, и этого просто не было для PHP еще.

Изменить: Хорошо, я неправильно прочитал этот вопрос. Возникает вопрос: как хранятся строки внутри? Если я набираю "Währung" или "Écriture", какой Encoding используется для создания используемых байтов? В случае PHP это ASCII с Codepage. Это означает: если я кодирую строку, используя ISO-8859-15, и вы декодируете ее с помощью какой-либо китайской кодовой страницы, вы получите странные результаты. Альтернатива в таких языках, как С# или Java, где все хранится как Unicode, что означает: больше нет кодовой страницы, и теоретически вы не можете испортить. Я рекомендую статью Joel о Unicode и наборах символов, но по существу это сводится к: Как хранятся строки внутри, а ответ с PHP - "Нет в Unicode", что означает, что вы должны быть очень осторожны и ясны при обработке строк, чтобы всегда держать строку в правильной кодировке во время ввода, хранения (базы данных) и вывода, что очень ошибочно.

Ответ 2

Я считаю, что это в значительной степени культурная сложность, а не техническая.

как для технических проблем --- и его не совсем тривиально реализовать юникод в экосистеме, построенный на предположениях, что "один символ равен одному байту" - разработчики могли бы скопировать большую часть java или python-усилий (последний с приличной и в значительной степени совместимой с Unicode совместимостью с 2001 года), но они так и не сделали.

когда я читаю дискуссионную тему, прикрепленную к официальной текущей документации для функции php utf8_encode(), я получаю чувство головокружения.

firstoff, эта функция называется utf8_encode(); однако в документации указано, что ожидаемая строка ожидается в ISO-8859-1 (a.k.a. latin-1). что sooo php, что sooo 80s.

Большинство комментаторов, похоже, воспринимают unicode как бремя. есть много предложений о том, как преобразовать строки "неизвестного контента", как обращаться с s'strings со смешанными кодировками (wtf?) или иметь дело с кодовыми точками, которые обычно вызывают обрыв, потому что они находятся за пределами этой функции. Четыре байта на каждый, конечный предел.

обсуждение сосредоточено вокруг исправлений, чтобы избавиться от squiggles или избежать проблемных частей поведения этой функции. и для меня это sooo php: все просто делают исправления, несколько вещей реализованы в принципиально правильном виде. если вы считаете, что это клевета на моей стороне, вот некоторые лакомые кусочки:

Хотя это, кажется, нарушает немецкий Umlaute [äöü], если документ уже UTF-8.

(неспособность понять, что utf-8 не предназначен для работы при применении дважды)

Посмотрите на функцию iconv(), которая предлагает способ конвертировать из 8859 и страшно 1252 в UTF8

(хорошая точка: игнорирование предшествующего уровня техники на стороне разработчиков php, вместо этого - неправильная реализация)

использование preg_match для обнаружения необходимости использования utf8_encode [...] исключая суррогатов [...], исключая перекрытия

(предлагая тихо стереть все проблемное содержимое из строк, оставив только те вещи, которые не сломаются utf8_encode(), это может сделать тексты нечитаемыми (или вообще исчезнуть), но эй, больше никаких сообщений об ошибках)

для кодирования строки, только если она еще не UTF-8 [...] mb_detect_encoding($s, "UTF-8")

(как было указано другим комментатором, это не сработает:

$str = 'áéóú'; // ISO-8859-1
mb_detect_encoding($str, 'UTF-8'); // 'UTF-8'
mb_detect_encoding($str, 'UTF-8', true); // false

поэтому здесь мы рассматриваем замену одной ошибки другой. хорошей охоты. также, что они, по-видимому, предлагают здесь, решить проблему с использованием эвристики (медленной, неопределенной), которая может и должна решаться с помощью механических (быстрых, определенных) средств)

utf8_ [encode | decode] будет фактически переводить символы Windows-1252, а не только из/в ISO-8859-1, как говорится в документации

(вы никогда не можете полагаться на официальную документацию php, чтобы быть ясной или исчерпывающей), вы всегда должны читать через годы опыта пользователей, которые никто никогда не будет возвращать в документы)

Я работал над функцией is_utf8 и хотел опубликовать его здесь, в дополнение к другим, я также принял во внимание ошибку 5000 char

(исправление для проблемы, которая в основном существует только потому, что unicode не реализована должным образом). Мы также узнаем, что функция utf8_encode() не только выйдет за пределы 4 байта на один код, она также сломается, если результат (или вывод?) превышает предел 5000 символов)

Я мог бы продолжать и продолжать. вы уже поняли: судя по этой теме, сообщество php просто не похоже, что они где-нибудь готовы понять, какие кодировки и наборы символов - все, что нужно для создания звуковой инфраструктуры вообще или, в частности, для реализуйте unicode надлежащим образом. вместо этого они используют свои леса, их картон, гвозди и молотки и продолжают строить это грандиозное здание под названием php, бросая свою клейкую ленту при любых проблемах, которые нельзя отменить другим гвоздем. конечно, что здание будет страдать от каждого ветра, который дует, например, случайного юридического, но неожиданного характера.

видя, что этот конкретный поток активен в течение восьми лет, точно не внушает уверенности, что ситуация станет лучше через восемь лет.

Ответ 3

Концепция "многобайтового символа" лежит в основе проблемы.

  • Он устраняет детали реализации: вы должны иметь возможность работать с абстракцией персонажа, не зная, как разработчики предпочитают представлять данные - возможно, в зависимости от платформы, которая им подходит, чтобы представлять все как UTF16 или UTF32, в котором случай все многобайтовый, а не то, что пользователи абстракции символов должны заботиться.
  • Это kludge: В дополнение к устаревшей привычке мысли, где все мы "действительно знаем", что строки являются байтовыми последовательностями, теперь мы должны знать, что иногда байты объединяются в вещи, известные как символы Unicode, и иметь особые случаи повсюду, чтобы справиться с этим.
  • Это как мышь, пытающаяся съесть слона. Обрабатывая Unicode как расширение ASCII (у нас есть обычные строки, и у нас есть mb_strings), он получает вещи не так, и получает зависание от того, какие особые случаи необходимы для работы с символами с забавными squiggles, которым требуется более одного байта. Если вы рассматриваете Unicode как предоставление абстрактного пространства для любого персонажа, который вам нужен, ASCII размещается в нем без необходимости рассматривать его как особый случай.

Ответ 4

Вы сами говорите: для правильной обработки строк, содержащих многобайтовые символы, вам необходимо использовать расширение. Забудьте где-нибудь использовать функции расширения вместо более привычных "нормальных", а ваши данные искалечены. То же самое происходит, если вы используете стороннюю библиотеку, которая не была обновлена, чтобы использовать функцию расширения повсюду.

Кроме того, ряд чрезвычайно популярных кодировок по-прежнему явно не поддерживается PHP, по-видимому, потому что это невозможно сделать и оставаться совместимым вниз.

Ответ 5

Многие из общих расширений не поддерживают юникод или (что еще хуже) вам "нужно знать", что строка содержит последовательности unicode/utf-8, например XMLReader. И это может иметь значение. PHP glob() вызывает FindFirstFileA или FindFirstFileW на win32.
Другой (гораздо меньший, но удивительно часто являющийся источником раздражения) проблемой - это спецификации, которые PHP не распознает.

Ответ 6

Многие из строковых функций - это всего лишь тонкие обертки вокруг эквивалентов библиотеки C, которые также обрабатывают все как последовательность байтов. Другая причина в том, что PHP несет в себе много ненужного багажа с обратной совместимостью и, таким образом, застрял с плохими проектными решениями от 3 & 4.

Возможно, с 5,3 пространствами имен у них, наконец, будет возможность поэтапного отключения старых функций.

Ответ 7

Под "поддержкой" подразумевается "встроенная поддержка". Посмотрите этот, чтобы получить подробную информацию.