Переход от PHP/FI 2.0 к PHP 3.0
Несовместимость в 3.0
PHP 3.0 полностью изменен. Его лексический анализатор стал намного более логичным и последовательным чем 2.0; версия 3.0 быстрее, и использует меньше ресурсов. Однако, некоторые усовершенствования повлекли частичную несовместимость в синтаксисе и функциональных возможностях.
Кроме того, в PHP 3.0 улучшен синтаксис и семантика, что также повлекло некоторую несовместимость. Однако, мы надеемся, что все эти усовершенствования к лучшему.
Эта глава поможет вам решить проблемы связанные с несовместимостью при переходе от PHP/FI 2.0 к PHP 3.0. Новые возможности здесь не рассматриваются.
Существует программа, которая может автоматически конвертировать старый PHP/FI 2.0 скрипт; вы можете найти ее в подкаталоге convertor дистрибутива PHP 3.0. Эта программа только отслеживает изменения синтаксиса, поэтому, в любом случае, вам придется прочитать эту главу внимательно.
Открывающий и закрывающий тэги
Первое, что вы вероятно заметите - это то что открывающий и закрывающий тэги PHP изменены. Старая > форма была заменена тремя новыми возможными формами:
Пример. Изменение: старые открывающий и закрывающий тэги:
<? echo "This is PHP/FI 2.0 code.\n"; >
Начиная с версии 2.0, PHP/FI поддерживает также следующий формат:
Пример. Изменение: новые открывающий и закрывающий тэги, первый вариант:
<? echo "This is PHP 3.0 code!\n"; ?>
Заметьте, что закрывающий тэг теперь состоит из знака вопроса и знака "больше" вместо только "больше". Однако, если Вы планируете использовать XML на вашем сервере, у вас будут проблемы с этим вариантом, так как PHP может попробовать исполнить разметку XML в документах XML как код PHP. Из-за этого, было внесено следующее изменение:
Пример. Изменение: новые тэги начала и конца, второй вариант:
<?php echo "This is PHP 3.0 code!\n"; ?>
Из-за проблем с редакторами, не поддерживающими инструкции обработки (например Microsoft FrontPage), были введены следующие изменения:
Пример. Изменение: новые тэги начала и конца, третий вариант:
<script language="php">
echo "This is PHP 3.0 code!\n";
</script>
Синтаксис операторов if..endif
"Альтернативный" способ описания блока if/elseif/else, с использованием, if(); elseif (); else; endif; не мог быть эффективно осуществлен без серьезного усложнения компиллятора/интерпретатора, из-за этого его синтаксис был изменен:
Пример. Изменение: старый синтаксис if..endif:
if ($foo); echo "yep\n"; elseif ($bar); echo "almost\n"; else; echo "nope\n"; endif;
Пример. Изменение: новый синтаксис if..endif:
if ($foo): echo "yep\n"; elseif ($bar): echo "almost\n"; else: echo "nope\n"; endif;
Точки с запятой были заменены двоеточиями во всех операторах, за исключением завершающего блок (endif).
Синтаксис while
Точно так же как, с if..endif, был изменен синтаксис while..endwhile:
Пример. Изменения: старый, while..endwhile синтаксис:
while ($more_to_come); ... endwhile;
Пример. Изменения: новый синтаксис while..endwhile:
while ($more_to_come): ... endwhile;
Внимание! Используя устаревший синтаксис в PHP 3.0 вы получите бесконечный цикл.
Типы выражений
В PHP/FI 2.0 использовалась левая часть выражения для определения типа результата. PHP 3.0 учитывает обе части выражения для определения типа результата; это может привести к неожиданным результатам работы скриптов 2.0.
Рассмотрите этот пример:
$a[0]=5; $a[1]=7;
$key = key($a); while ("" != $key) { echo "$keyn"; next($a); }
В PHP/FI 2.0 мы получили бы индексы $a. В PHP 3.0 мы не увидим ничего. Причина в том что в PHP 2.0, переменная в левой части выражения - строка; было выполнено сравнение, действительно "" не равно "0", и цикл был пройден. В PHP 3.0, при выполнении операции сравнения строковой и целочисленных переменных, строка будет преобразована в целое число и далее аргументы сравниваются как целые. Это означает в данном случае, что сравненивается значение функции atoi("") которое равно 0, и variablelist которое также равно 0; цикл не выполняется ни разу.
Исправить это достаточно просто. Замените начало на:
while ((string)$key != "") {
Изменены сообщения об ошибках
Сообщения об ошибках PHP 3.0, как правило, точнее чем в 2.0. Вместо указания фрагмента кода, вызвавший ошибку, вы получаете имя файла и номер строки.
Сокращенная операция вычисления логических выражений
В PHP 3.0 используется метод сокращенного вычисления логических выражений. Это означает что в выражении (1 || test_me()), функция test_me() не вызывается, так как результат функции уже не сможет изменить результат этого логического выражения.
Эта незначительная, на первый взгляд, проблема совместимости может приести к неожиданным последствиям. Значения true/false, возвращаемые функциями
Большинство внутренних функции были переписаны; теперь они возвращают TRUE, в случае удачи и FALSE в противном случае, тогда как в PHP/FI 2.0 возвращаются 0 и -1 соответственно. Эти новые возможности позволяют создавать более логичный код, такой так $fp = fopen("/your/file") or fail("darn!");. Так как PHP/FI 2.0 не имел четких правил, относительно того, что должна вернуть функция в случае неудачи, в большинстве случаев скрипты использующие подобные функции должны быть проверены вручную после проверки конвертером.
Пример. Изменения 2.0: возвращаемые значения, старый код:
$fp = fopen($file, "r"); if ($fp == -1); echo("Could not open $file for reading<br>\n"); endif;
Пример. Изменения 2.0: возвращаемые значения, новый код:
$fp = @fopen($file, "r") or print("Could not open $file for reading<br>\n");
Прочие изменения
Модуль Apache в PHP 3.0 не поддерживает Apache версий до 1.2. - необходима версия Apache 1.2, или более поздняя. echo() больше не поддерживает строку формата. Используйте printf().
В PHP/FI 2.0, вызов $foo[0] имел тот же эффект как и $foo. Это устранено в PHP 3.0.
Чтение массивов в виде $array[] больше не поддерживается
То есть вы не можете читать массив в цикле, выполняющем $data = $array[]. Используйте current()и next().
Кроме того, выражение $array1[] = $array2 не добавляет значения массива $array2 к $array1, но добавляет $array2 как последний элемент $array1. См. также поддерку многомерных массивов.
"+" Больше не используется как оператор сложения для строковых переменных, вместо этого они преобразовываются к целочисленным и выполняется операция сложения. Используйте ".".
Пример. Изменения 2.0: сложение для строковых переменных
echo "1" + "1";
В PHP 2.0 значение этого выражения - 11, а в PHP 3.0 - 2. Используйте вместо него:
echo "1"."1"; $a = 1; $b = 1; echo $a + $b;
Значение этого выражения = 2 для PHP 2.0 и 3.0.
$a = 1; $b = 1; echo $a.$b;
Это выражение вернет 11 в PHP 3.0.
1 2 3
8 8 8
| |