Этот вопрос начинает упоминать имена классов в заголовке, но затем переходит к примеру, который включает экзотические имена для методов, констант, переменных и полей.Есть на самом деле разные правила для них.Давайте начнем с регистра без учета регистра.
Идентификаторы без учета регистра (имена классов и функций / методов)
Общее руководство здесь заключается в использовании только печатных символов ASCII.Причина в том, что эти идентификаторы нормализованы к их строчной версии, однако это преобразование зависит от локали.Рассмотрим следующий PHP-файл, закодированный в ISO-8859-1:
<?php
function func_á() { echo "worked"; }
func_Á();
Будет ли работать этот скрипт?Может быть.Это зависит от того, что tolower
(
193
)
вернется, что зависит от локали:
$ LANG=en_US.iso88591 php a.php
worked
$ LANG=en_US.utf8 php a.php
Fatal error: Call to undefined function func_Á() in /home/glopes/a.php on line 3
Следовательно, это нехорошая идея использовать не-ASCII символы.Однако даже символы ASCII могут создавать проблемы в некоторых локалях.См. это обсуждение .Вполне вероятно, что это будет исправлено в будущем с помощью независимого от локали нижнего регистра, который работает только с символами ASCII.
В заключение, если мы используем многобайтовые кодировки для этих нечувствительных к регистру идентификаторов, мыищу неприятности.Мы не просто не можем использовать нечувствительность к регистру.Мы можем фактически столкнуться с неожиданными коллизиями, потому что все байты, которые составляют многобайтовый символ, индивидуально превращаются в строчные буквы с использованием правил локали.Возможно, что два разных многобайтовых символа отображаются в одно и то же измененное представление потока байтов после применения правил строчных букв локали к каждому из байтов.
Идентификаторы с учетом регистра (переменные, константы, поля)
Проблема здесь менее серьезна, так как эти идентификаторы чувствительны к регистру.Тем не менее, они просто интерпретируются как потоки.Это означает, что если мы используем Unicode, мы должны последовательно использовать одно и то же представление байтов;мы не можем смешивать UTF-8 и UTF-16;мы также не можем использовать спецификации.
На самом деле, мы должны придерживаться UTF-8.Вне диапазона ASCII UTF-8 использует ведущие байты от 0xc0 до 0xfd, а байты следа находятся в диапазоне от 0x80 до 0xbf, которые находятся в допустимом диапазоне согласно руководству.Теперь допустим, что мы используем символ «Ġ» в кодированном файле UTF-16BE.Это преобразуется в 0x01 0x20, поэтому второй байт будет интерпретироваться как пробел.
Если многобайтовые символы читаются так, как если бы они были однобайтовыми символами, это, конечно, вообще не поддерживает Unicode.PHP имеет некоторую многобайтовую поддержку в виде переключателя компиляции «--enable-zend-multibyte» (в PHP 5.4 поддержка многобайтовых данных компилируется по умолчанию, но отключена; вы можете включитьэто с zend.multibyte=On
в php.ini).Это позволяет вам объявить кодировку сценария:
<?php
declare(encoding='ISO-8859-1');
// code here
?>
Он также будет обрабатывать спецификации, которые используются для автоматического определения кодировки и не становятся частью выходных данных.,Есть, однако, несколько минусов:
- Удар Peformance, как памяти, так и процессора.Он хранит представление скрипта во внутренней многобайтовой кодировке, которая занимает больше места (и, похоже, также хранит в памяти исходную версию), а также тратит некоторое количество ресурсов процессора для преобразования кодировки.
- Multi-Поддержка байтов обычно не компилируется, поэтому она менее проверена (больше ошибок).
- Проблемы переносимости между установками, в которые встроена поддержка, и теми, которые не поддерживают.
- Относится только кэтап разбора; не решает проблему, описанную для нечувствительных к регистру идентификаторов.
Наконец, существует проблема отсутствия нормализации - один и тот же символ может быть представлен различными кодовыми точками Unicode (независимо от кодировки).Это может привести к некоторым очень трудным для отслеживания ошибок.