Поэтому я сомневаюсь, правда ли, что строковые литералы в PHP могут быть закодированы только в кодировке, которая является совместимым расширенным набором ASCII, такой как UTF-8 или ISO-8859-1, а не в кодировкекоторый не является совместимым надмножеством ASCII?
Это не так.
Возможно ли кодировать строковые литералы в PHP в некоторых не ASCII-совместимых кодировках, таких как UTF-16, UTF-32 или какая-то другая не ASCII-совместимая кодировка?Если да, то будут ли строковые литералы, закодированные в такой кодировке, не совместимой с ASCII, работать с функциями mb_string_ *?Если нет, то в чем причина?
Как говорит @deceze, вы можете легко преобразовать строку в нужную вам кодировку с помощью mb_convert_encoding или iconv .
Из Сведения о типе строки в PHP Manual, String будет закодирован любым способом, который закодирован в файле сценария.PHP, созданный с поддержкой Zend Multibyte
и расширением mbstring
, может анализировать и запускать файлы PHP, закодированные в кодировке, не совместимой с ASCII, например UTF-16, см. Тесты в Zend / многобайтовых .
Zend/tests/multibyte/multibyte_encoding_003.phpt
продемонстрировано для запуска источников с кодировкой UTF-16 LE, которые правильно выводят Hello World.
Zend / tests / multibyte / multibyte_encoding_003.phpt
--TEST--
Zend Multibyte and UTF-16 BOM
--SKIPIF--
<?php
if (!in_array("zend.detect_unicode", array_keys(ini_get_all()))) {
die("skip Requires configure --enable-zend-multibyte option");
}
if (!extension_loaded("mbstring")) {
die("skip Requires mbstring extension");
}
?>
--INI--
zend.multibyte=1
mbstring.internal_encoding=iso-8859-1
--FILE--
<?php
print "Hello World\n";
?>
===DONE===
--EXPECT--
Hello World
===DONE===
$ run-tests.php --keep-php --show-out --show-php Zend / tests / multibyte / multibyte_encoding_003.phpt
... skip some trivial message ...
Running selected tests.
TEST 1/1 [multibyte_encoding_003.phpt]
========TEST========
<?php
print "Hello World\n";
?>
===DONE===
========DONE========
========OUT========
Hello World
===DONE===
========DONE========
PASS Zend Multibyte and UTF-16 BOM [multibyte_encoding_003.phpt]
=====================================================================
Number of tests : 1 1
Tests skipped : 0 ( 0.0%) --------
Tests warned : 0 ( 0.0%) ( 0.0%)
Tests failed : 0 ( 0.0%) ( 0.0%)
Expected fail : 0 ( 0.0%) ( 0.0%)
Tests passed : 1 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken : 0 seconds
=====================================================================
$файл multibyte_encoding_003.php
multibyte_encoding_003.php: PHP script text, Little-endian UTF-16 Unicode text
Другой пример - Zend/tests/multibyte/multibyte_encoding_004.phpt
, он запускает источник с кодировкой Shift JIS .
Zend / tests/multibyte/multibyte_encoding_004.phpt (Примечание. Некоторые японские символы отображаются неправильно из-за смешивания кодировки в одном файле, а для LC_MESSAGE
установлено значение UTF-8
)
--TEST--
test for mbstring script_encoding for flex unsafe encoding (Shift_JIS)
--SKIPIF--
<?php
if (!in_array("zend.detect_unicode", array_keys(ini_get_all()))) {
die("skip Requires configure --enable-zend-multibyte option");
}
if (!extension_loaded("mbstring")) {
die("skip Requires mbstring extension");
}
?>
--INI--
zend.multibyte=1
zend.script_encoding=Shift_JIS
mbstring.internal_encoding=Shift_JIS
--FILE--
<?php
function \\\($)
{
echo $;
}
\\\("h~t@\");
?>
--EXPECT--
h~t@\
$run-tests.php --keep-php --show-out --show-php
./multibyte_encoding_004.phpt
... skip some trivial message ...
Running selected tests.
TEST 1/1 [multibyte_encoding_004.phpt]
========TEST========
<?php
function \\\($)
{
echo $;
}
\\\("h~t@\");
?>
========DONE========
========OUT========
h~t@\
========DONE========
PASS test for mbstring script_encoding for flex unsafe encoding (Shift_JIS) [multibyte_encoding_004.phpt]
=====================================================================
Number of tests : 1 1
Tests skipped : 0 ( 0.0%) --------
Tests warned : 0 ( 0.0%) ( 0.0%)
Tests failed : 0 ( 0.0%) ( 0.0%)
Expected fail : 0 ( 0.0%) ( 0.0%)
Tests passed : 1 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken : 0 seconds
=====================================================================
$ file Zend / tests / multibyte / multibyte_encoding_004.php
multibyte_encoding_004.php: PHP script text, Non-ISO extended-ASCII text
$ cat Zend / tests / multibyte / multibyte_encoding_004.php |iconv -f SJIS -t utf-8
<?php
function 予蚕能($引数)
{
echo $引数;
}
予蚕能("ドレミファソ");
?>
Возможно ли кодировать строковые литералы в PHP в некоторых кодировках, не совместимых с ASCII, таких как UTF-16, UTF-32 или некоторые другиедругое такое не ASCII-совместимое кодирование?Если да, то будут ли строковые литералы, закодированные в такой кодировке, не совместимой с ASCII, работать с функциями mb_string_ *?Если нет, то в чем причина?
Ответ на первый вопрос - да, тесты для Zend Multibyte
убедительно продемонстрированы.Ответ на второй вопрос также положительный, если дать правильные подсказки кодирования для mb_string_*
.
Предположим, Zend Multibyte включен, и я установил внутреннюю кодировку для совместимого расширенного набора ASCII,такие как UTF-8 или ISO-8859-1 или некоторые другие не ASCII-совместимые кодировки.Теперь я могу объявить кодировку, которая не является совместимым надмножеством ASCII, например UTF-16 или UTF-32, в файле сценария?
Если да, то в этом случае, какую кодировку получат строковые литералызакодировано в?Если нет, то в чем причина?
Да, выходные данные, генерируемые второй командой, представляют собой кодировку UTF-32 (представляет один символ в виде 4 байтов)
$ echo -e '<?php\necho "Hello 中文";' | php | hexdump -C
00000000 48 65 6c 6c 6f 20 e4 b8 ad e6 96 87 |Hello ......|
0000000c
$ echo '<?php\\necho "Hello 中文";' | iconv -t utf-16 | php -d zend.multibyte=1 -d zend.script_encoding=UTF-16 -d mbstring.internal_encoding=UTF-32 | hexdump -C
00000000 00 00 00 48 00 00 00 65 00 00 00 6c 00 00 00 6c |...H...e...l...l|
00000010 00 00 00 6f 00 00 00 20 00 00 4e 2d 00 00 65 87 |...o... ..N-..e.|
00000020
Также, объясните мне, как эта штука кодирования работает для строковых литералов, если включен Zend Multibyte?
Функция Zend Multibyte реализована в Zend / zend_multibyte.c , Пусть движок Zend знаетбольше кодирования, чем Ascii и UTF-8, это только интерфейс для кодирования, потому что реализация по умолчанию - фиктивная функция , реальная реализация - расширение mbstring
, поэтому mbstring
является обязательнымрасширение для получения многобайтовой поддержки при загрузке .
$ php -m | grep mbstring
mbstring
$ php -n -m | grep mbstring # -n disable mbstring, No configuration (ini) files will be used.
$ echo -e '<?php\n echo "Hello 中文\n"; ' | iconv -t utf-16 | php -n -d zend.multibyte=1
Fatal error: Could not convert the script from the detected encoding "UTF-32LE" to a compatible encoding in Unknown on line 0
Как включить Zend Multibyte?Каково главное намерение включить его?Когда требуется включить его?
Объявите zend.multibyte = 1 в php.ini, чтобы включить разбор исходных файлов в многобайтовых кодировках. Также вы можете передать -d zend.multibyte=1
в исполняемый файл PHP Cli, как в примере выше, чтобы включить многобайтовую поддержку в PHP Zendдвигатель.