Как стать автором
Обновить

Комментарии 62

> на Амазоне до сих пор полно книг «Learn PHP6 in 1 hour»

Спасибо Вам огромное — это просто великолепно!
Как говорят у нас в интернетах, «ржушодурной»… :)
Один ревью прекраснее другого :)
Интересно, через сколько она теперь выйдет. Тот же PHPng вроде как еще пилить и пилить.
> и была прекращена в 2010 из-за сложностей с реализацией поддержки Юникода. Поэтому все нововведения PHP6, кроме той самой поддержки, были потом реализованы в PHP 5.3 и PHP 5.4

Так а в семерке ее таки сделают же, да?
Нет.
От этих планов в принципе отказались.
От этих планов в принципе отказались.

Ну это уже совсем не серьезно — отказываться от поддержке юникода в языке сегодня!
Я даже не буду пытаться язвить на счет PHP — они сами отлично все сделали ;)
Можно язвить, можно не язвить, это вкусовщина.

Поддержку юникод необходимо было добавлять на этапе разработки ядра, теперь это попросту ломает всё.
А что вообще в себя включает «поддержка уникод»?
Нативная работа со всеми строками, как с уникодом — без костыльных решений, вроде mb_*, причем был выбран за основу UTF-16, что еще больше усложнило разработку. В итоге плюнули на это. Где-то был обширный пост, разъясняющий почему конкретно разработчики забили, но сейчас нет времени искать.
Ага, нашёл там такое

Что хотелось иметь

Так а в чём проблема спросите вы? Есть mbstring, используй и радуйся.
А дело в том, что разработчики решили поддержать юникод не на уровне библиотеки, а на уровне ядра. Это означает, что любая php-функция, а также строковые операторы, в потенциале, могут принимать в себя юникод и более менее гарантировать, что юникод символы не будут исковерканы, удалены и не произойдёт ошибки. Кроме того, сам mbstring реализует далеко не все стандартные строковые функции.
Предположим, что в некотором скрипте PHP все строки содержат текст в кодировке UTF-8.

Если оставить в стороне вопрос о том, что PHP считает их размер в байтах, а не в символах, то что может пойти не так («символы исковерканы, удалены, ошибки») по сравнению со строками в обычной восьмибитной кодировке?

Может ли один символ найтись вместо другого? — нет, потому что в UTF-8 однобайтовые символы (ASCII-символы) имеют старший бит «0», а у многобайтовых последовательностей UTF-8 начальные байты имеют старшие биты «11», тогда как остальные байты (включая конечные) имеют старшие биты «10». Следовательно, перепутать эти три категории байтов кода никак нельзя.

Тогда что не будет работать, кроме подсчёта длины строк или позиции в строке? Я пока могу только один пример придумать: классы символов в регулярных выражениях.
Да нет особых проблем от того, что пхп работает со строками как с массивами байт. Проблемы появляются, когда само ядро языка пытаются научить работать с юникодом, что очень сильно усложняет код (ядра) и очень сильно бьет по производительности. В итоге становится понятна, что эта пресловутая «поддержка юникода» просто не стоит того.
Подсчёт длины строк не очень полезен, поскольку он идёт в кодпойнтах, а люди считают графемами (знак ударения — простейший пример: люди за символ его не считают. Впрочем, считать в кодпойнтах иногда тоже нужно, иначе можно забить БД zalgo в 5 миллионов кодпойнтов в каждом поле «ник», игнорируя ограничения в 15 графем). Проблемы будут при попытках делать с текстом хоть что-то (например, искать подстроку с учётом канонической эквивалентности либо сортировать, учитывая локаль), но об этих вещах даже в языках с «поддержкой юникода» нужно думать самим (нестареющий пример с перлом, многие вещи справедливы и для «умеющих юникод из коробки» языков). Поэтому именно решение не уметь юникод в ядре языка — вполне себе практичное. Позволит, в конце концов, писать более-менее эффективные библиотеки работы с протоколами (все служебные слова которых как правило в ASCII), используя все удобства работы со строками, а не как в python3: либо оверхэд на работу с юникодом (те же поиск и collation не бесплатны), либо байтстринги, у которых нет даже .format().

У PHP есть много минусов, но лично мне неумение юникода кажется не сильно страшным. Не понимаю, почему минусуют. Также неумение юникода в ядре позволит реализовывать любые кодировки уровнем выше без каких-либо ограничений.
Более того — и с регулярными выражениями вообще нет никаких проблем — в php используется библиотека pcre, и в любом регулярном выражении можно в явном виде задать unicode-режим (/u).
теперь это попросту ломает всё

Ну выбор у создателей PHP не большой:
* Сломать и сделать поддержку.
* PHP-разработчики должны страдать! (дьявольский смех)

Не выберут ли в этом случае сами PHP-разрабочики постепенную миграцию на тот же Python 3 (который пусть и с большим трудом но постепенно увеличивает свою долю)?
PHP выбирают не за поддержку юникода и, по моему мнению, этот вопрос встанет последним в принятии решения о миграции на другой язык. Не за это и питон выбирают :)
PHP выбирают не за поддержку юникода

Полностью согласен — как и любой другой язык.
Да и не думаю, что в ближайшие годы PHP «умрет» от отсутствия юникода.
Вопрос немного в другом — при наличие альтернатив у разработчиков всегда закрадываются мысли посмотреть их, попробовать и кто знает к чему это приведет, если альтернативы окажутся более удобны (PHP все же не C/C++ от которых никуда не деться сейчас) ;)
А в чем выражаются ваши страдания? В том что не можете как в 1С писать?
Неужели формулировку «PHP-разработчики должны страдать! (дьявольский смех)» можно понять так буквально :) Просьба читать ее как: «PHP-разработчики должны испытывать некоторые неудобства».

Выше есть ссылка на топик про отказ от юникода в PHP6. В комментариях упоминаются отдельные неудобства которые это создает, например этот комментарий.

Лично я не являюсь PHP-разработчиком и в работе использую язык с поддержкой юникода. При возникновении необходимости что-то сделать на языке без поддержки юникода Python 2.x, C — сразу видно, что с юникодом жить приятнее. И надеюсь, что рано или поздно PHP разработчикам тоже облегчат жизнь.
Понял, желать что: «PHP разработчикам тоже облегчат жизнь» — на Хабре нельзя, минусуют PHP-ненавистники ;)
В PHP, в принципе, и сейчас русские буквы в названиях функций/переменных отлично работают.
Может быть, но вот символ «§» в именах классов (потому что «-» нельзя!) вызывает у нас (PHP 5.3) редкую и нерегулярную ошибку.
php.net/manual/en/language.variables.basics.php
As a regular expression, it [variable name] would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'

<?php
$сколькоРаз = 5;

$функция = function($значение) use ($сколькоРаз) {
    printf("%d из %s\n", $значение, $сколькоРаз);
};

for ($номер = $сколькоРаз; $номер; --$номер) {
    $функция($номер);
}


Прекрасно работает для utf8 исходника. Но так же делать не стоит?:)
Значит, надо ломать. Возможно, как питон, поддерживать две ветки некоторое время.

Но любая другая стратегия — это отодвигание решения проблемы на потом. Причем, чем дольше отодвигают, тем сложнее будет решать (потому что больше сломается).
Как-то странно это, всё же. Что же это за сложности такие, что чуваки их никак не преодолеют? Учитывая опыт второго и третьего питонов (и набитых при этом шишек).
В посте есть ссылка на статью, там написано.
Конечно же такие штуки как AST и native big integers важнее и нужнее в web-разработке чем какой-то там Юникод. Всякому понятно. :)
Почитал статью, спасибо за ссылку. Ну детские проблемы какие-то. Я согласен, что задача непростая, и тонкостей там вагон с тележкой (в тексте Армина Ронахера некоторые из них описаны достаточно подробно, чтобы оценить масштаб), но основные грабли в общем-то давно известны, и жаловаться на отсутствие специалистов по юникоду и неудачный выбор UTF-16 в 2014 г. уже как-то несерьезно.
Есть же дефолтные функции *_mb, почему бы их не использовать вместо стандартных? Сам пользую уже лет пять, как-то даже не заметил отсутствие нативной поддержки юникода если честно…
Я бы не был столь категоричен. Отказались в принципе от реализации юникода в PHP6 на базе UTF-16 в том виде, как они собирались. И, насколько я помню, когда официально было заявлено, что «шестерке — кирдык», то одной из ключевых причин назывался принципиально неверный подход к реализации поддержки юникода (в т.ч. и выбор UTF-16). Что будет в «семерке» и не будет ли предпринята новая попытка поддержать юникод, но с иным подходом — пока неизвестно. Или уже есть какие-то официальные заявления на этот счет?
Возможно вы правы, в wiki у них есть предложения по использованию 3rd-party библиотек, чтобы впилить поддержку utf-8 (а не 16) в ядро. Но они пока что только с именем и определились, а судя по проекту PHPNG их сейчас гораздо больше волнует производительность движка (на фоне неиллюзорной конкуренции со стороны HHVM)
Главное, чтобы не вышло как с питоном.
А что случилось с питоном? Что-то я не в курсе, где почитать?
Ну так юникода, как раз, не будет. Имелась ввиду, вероятно, потеря обратной совместимости при переходе от Python 2 к Python 3.
А об обратной совместимости я даже писать не хотел. Я думал это и так очевидно :)
Случилось ужасное — он получил поддержку юникод ;) (в какой-то степени слово 'ужасное' действительно применимо — см. ссылку из соседнего комментария)
Вполне ожидаемо.
А у меня есть такой слоник)

Слоник
image
Откуда? У меня только синие.
Клево. А то у меня только три синих.
Главное, что не зелёных.
А что плохого в зеленых elePHPant'ах? :)
Да ничего, им просто плохо в клетке жить…
Уникальные в своем роде)
НЛО прилетело и опубликовало эту надпись здесь
А вот в ядро Delphi поддержку Unicode запилили в версии Delphi 2009. Причем жестоко запилили: тип String, представлявший собой в предыдущих версиях строку однобайтных символов, вдруг стал строкой из символов 2-х байтных. И объем строки в байтах стал не Length(s), a 2*Length(s), а точнее SizeOf(Char)*Length(s), т.к. сам тип Char тоже превратился из 1 байта в 2. Это сразу сломало совместимость с новой версией большей части имеющихся проектов, но ничего, попыхтели немного — привели код в порядок, всё снова заработало, зато теперь Unicode не только в самом языке (во всех функциях, принимающих на входе строки), но и во всех визуальных компонентах, причем из коробки. Работать с этим довольно приятно.
То есть люди перешли на UTF-16, я правильно понимаю? Тогда (как и в JavaScript) их ждёт много небезынтересных откровений, связанных с существованием символов Unicode, имеющими номера более U+010000, для обозначения которых не достаточно двух байтов, не достаточно четырёх шестнадцатеричных цифр.
имеющими номера более U+010000

Не следует путать кодовые точки (номера символов в таблице Unicode, которые могут быть > 65535) и кодировку (UTF-8, UTF-16), которой эти точки кодируются.

Насколько я понимаю, UTF-16 так устроена, что для кодирования символов с кодом (кодовой точкой) > 65535 нужно использовать более одной пары байт. В обычных применениях такие символы (представленные суррогатными парами), как правило, не встречаются.

Цитирую википедию:
В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 0 до FFFF16). При этом можно кодировать символы Unicode в диапазонах 000016..D7FF16 и E00016..10FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами. Символы Unicode до FFFF16 включительно (исключая диапазон для суррогатов) записываются как есть 16-битным словом. Символы же в диапазоне 1000016..10FFFF16 (больше 16 бит) уже кодируются парой 16-битных слов. Для этого их код арифметически сдвигается до нуля (из него вычитается минимальное число 1000016). В результате получится значение от нуля до FFFFF16, которое занимает до 20 бит. Старшие 10 бит этого значения идут в лидирующее (первое) слово, а младшие 10 бит — в последующее (второе). При этом в обоих словах старшие 6 бит используются для обозначения суррогата. Биты с 11 по 15 имеют значения 110112, а 10-й бит содержит 0 у лидирующего слова и 1 — у последующего. В связи с этим можно легко определить к чему относится каждое слово.
То есть в существующем интерпретаторе PHP вообще нет AST?..
А зачем в интерпритаторе AST? Вообще да, в PHP довольно примитивный single-pass парсер. Наследие былых ошибок, так сказать.
Вообще забавно, помниться кода вопрос перехода на AST обсуждали в 2012-ом говорилось о снижении производительсности и необходимости использования опкод-кешеров. Судя по приведенным в RFC данным производительность разбора исходников наоборот увеличивается, причем потребление памяти вырастает незначительо, что не может не радовать.
Ну там же байткод генерируется, как я понимаю. Довольно типовая задача, и обычно проще решается именно с AST.
По сути. если мы рассматриваем именно интерпритатор, то он работает только с оп-кодом. AST — часть парсера/транслятора в опкоды. Вообще просто так повелось. Расмус Лердорф как-то говорил «I was really, really bad at writing parsers. I still am really bad at writing parsers». Так и повелось. Впервые о необходимости перехода на AST для парсеров заговорили довольно давно, вроде как в 2010-ом. К сожалению в 2012-ом решили что это слишком титанический труд и забросили это дело. Но с тех пор появилась почти готовая реализация оного, да и phpng это уже существенные изменения в ядре. Так что можно надеяться что в итоге перейдут на AST и расширять синтаксис PHP перестанет быть адской болью.
Собственно, это в посте написано.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории