Изменения, повлекшие за собой обратную несовместимость

Несмотря на то, что большинство кода на PHP 4 должно работать безо всяких изменений, вам следует обратить вимание на следующие изменения, повлекшие за собой обратную несовместимость:

  • Несколько новых зарезирвированных ключевых слов.

  • strrpos() и strripos() теперь используют всю строку как needle.

  • Неправильное использование смещения внутри строки вызывает E_ERROR вместо E_WARNING. Пример неправильного использования: $str = 'abc'; unset($str[0]);.

  • array_merge() изменена таким образом, что принимает в качестве аргумента только массивы. Если была передана переменная, не являющаяся массивом, будет сгенерированна ошибка E_WARNING для каждого такого параметра. Будьте внимательны, потому что ваш код может вдруг начать генерировать ошибки E_WARNING.

  • Переменная сервера PATH_TRANSLATED больше не определяется неявно под Apache2 SAPI, в отличие от ситуации в PHP 4, где ей присваивается то же значение, что и переменной сервера SCRIPT_FILENAME, когда она не определяется Apache. Это изменение было сделано для соответствия спецификации CGI. Пожалуйста, обратитесь к ошибке #23610 для получения дальнейший информации, а также посмотрите описание $_SERVER['PATH_TRANSLATED'] в данном руководстве. Это изменение также имеет место в PHP версий >= 4.3.2.

  • Константа T_ML_COMMENT больше не объявляется расширением Tokenizer. Если директива error_reporting установлена в E_ALL, PHP сгенерирует ошибку уровня E_NOTICE. Несмотря на то, что T_ML_COMMENT не использовалась вообще, она была объявлена в PHP 4. Как в PHP 4, так и в PHP 5 // и /* */ определяются как T_COMMENT. Так или иначе, комментарии /** */ в стиле PHPDoс, которые начиная с PHP 5 анализируются PHP, распознаются как T_DOC_COMMENT.

  • Суперглобальный массив $_SERVER будет создан вместе с переменными argc и argv, если variables_order включает "S". Если вы сконфигурировали интерпретатор таким образом, что $_SERVER не создаётся, тогда, конечно, её не будет. Изменение заключается в том, чтобы сделать argc и argv всегда доступными в CLI-версии, вне зависимости от variables_order. Как уже было сказано, CLI-версия теперь всегда будет объявлять переменные $argc и $argv.

  • Объект без свойств больше не считается "пустым".

  • В некоторых случаях класс должен быть объявлен перед использованием. Это происходит только в том случае, если используются некоторые новые функции PHP 5. Иначе поведение остается старым.

  • get_class(), get_parent_class() и get_class_methods() теперь возвращают имя классов/методов так, как они были объявлены (с учетом регистра), что может привести к проблемам со старыми скриптами, которые полагаются на прежнее поведение (имя класса/метода всегда было приведено к нижнему регистру). Возможным решением является поиск этих функций в ваших скриптах и добавление перед ними strtolower().

    Изменения относительно регистрозависимости также затрагивают магические константы __CLASS__, __METHOD__ и __FUNCTION__. Значения возвращаются в именно таком виде, в каком они обявлены (с учетом регистра).

  • ip2long() теперь возвращает FALSE, а не -1, когда в качестве аргумента функции передается неправильный IP-адрес.

  • Если во включенном файле объявлены какие-либо функции, они могут использоваться и в главном файле, вне зависимости от того, располагаются они до return() или после. Если файл включается дважды, PHP 5 генерирует фатальную ошибку, так как функции уже были объявлены, в то время, как PHP 4 не жалуется на это. Рекомендуется использовать include_once() вместо проверки, был ли уже включен файл и условного возврата внутри включенного файла.

  • include_once() и require_once() сначала стандартизируют путь к включенному файлу в Windows, так что при включении A.php и a.php файл включается только один раз.

Пример B-1. strrpos() и strripos() теперь используют всю строку как needle

<?php
var_dump
(strrpos('ABCDEF','DEF')); //int(3)

var_dump(strrpos('ABCDEF','DAF')); //bool(false)
?>

Пример B-2. Объект без свойств больше не считается "пустым"

<?php
class test { }
$t = new test();

var_dump(empty($t)); // echo bool(false)

if ($t) {
  
// Будет выполнено
}
?>

Пример B-3. В некоторых случаях классы должны быть объявлены перед использованием

<?php

//работает без ошибок:
$a = new a();
class
a {
}


//вызывает ошибку:
$a = new b();

interface
c{
}
class
b implements c {
}

?>



Изменения, повлекшие за собой обратную несовместимость
28-Feb-2006 02:03
is_a have been deprecated. You can simply replace all occurences with the new instanceOf operator, although this will break backwards-compatibility with php4.
dward . maidencreek.com
02-Nov-2004 12:54
Another change that we've had problems with while trying to use PHP4 code in PHP5 is how $this is carried across static method calls if they are not declared static in PHP5.  The main issue was that debug_backtrace() now shows the first class with -> instead of the second with :: in the backtrace element when the method in the second class was called statically (using ::) from a method in the first class.
07-Sep-2004 09:40
Be careful with array_merge in PHP5.1 not only a E_WARNING is thrown, but also the result is an empty array. So if you merge two select queries and the last one is empty you will end up with no array at all.

$array_1 = array('key1'=>'oranges','key2'=>'apples');

       $array_2 = array('key3'=>'pears','key4'=>'tomatoes');
       $array_3 = null;
       $arr_gemerged = array_merge($array_1,$array_2,$array_3);
       echo "result:<br>";
       print_r($arr_gemerged);
       echo "<br>";

Result on php4:
result:
Array ( [key1] => oranges [key2] => apples [key3] => pears [key4] => tomatoes )

Result on php5:
Warning: array_merge() [function.array-merge]: Argument #3 is not an array in /Library/WebServer/Documents/regis24/admin/test_array_merge.php on line 7
result:
john.g
26-Aug-2004 10:45
PATH_TRANSLATED is handy when using Apache's ModRewrite engine, as it gives you the name and path of the resulting file rather than the one that was requested by the user. Since PHP 5.0 and Apache 2 no longer support this variable, I created a workaround by adding an environment variable to my ModRewrite command:

Original:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2

Adjusted:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2 [E=TARGET:prefix_$1.php]

I could then find out the resulting file name through the super global $_ENV, for instance:

<?php
echo "The actual filename is ".$_ENV['REDIRECT_TARGET'];
?>

Note: The "REDIRECT_" prefix appears to be allocated automatically by ModRewrite.
cyberhorse
05-Aug-2004 10:07
clone() is a php function now.

if you create a subclass, it no longer uses samename methods in superclass as a constructor.
Justin Gehring
20-Jul-2004 01:34
One more thing that is not backwards compatible with PHP 5.0 (at least as far as we can tell) is the XSLT Sablotron librarys and the old DOM_XML librarys. Both have replacements, but translations will need to be made with either an alias class, or in the code itself.

-Justin Gehring
jbeall /\t heraldic d0t us
14-Jul-2004 07:17
Another change that was made is the behavior when you try to reassign $this.

Before, you could reassign $this from within an object, and thus change it to a different class.  Now, this results in a parse error.

<Миграция с PHP 4 на PHP 5CLI и CGI>
 Last updated: Tue, 15 Nov 2005