PHP Velho Oeste 2024

Cambios retroincompatibles

Aunque la mayoría del código existente en PHP 4 debe de correr sin modificaciones, se debe de prestar atención a los siguientes cambios incompatibles entre versiones:

  • Hay algunas palabras reservadas nuevas.
  • strrpos() y strripos() ahora utilizan todo el string como cadena de búsqueda.
  • El uso ilegal de los índices de las cadenas emite E_ERROR en lugar de E_WARNING. Un ejemplo de uso ilegal es: $str = 'abc'; unset($str[0]);.
  • array_merge() ha sido modificado para que sólo acepte matrices. Si se pasara una variable que no es un array, se emitiría un E_WARNING por cada parámetro. Debe tenerse cuidado para que un código no comience a emitir E_WARNING de la nada.
  • La variable de servidor PATH_TRANSLATED ya no se establece implicitamente en Apache2 SAPI tal como sucedía en PHP 4, donde se establecía el mismo valor que contenía la variable de servidor SCRIPT_FILENAME cuando ésta no estaba completada por Apache. Este cambio fue realizada para cumplir con las » Especificación CGI/1.1. Por favor consulte » bug #23610 para más información, vea tambien la descripción de $_SERVER['PATH_TRANSLATED'] en el manual. Este problema también afecta las versiones de PHP >= 4.3.2.
  • La constante T_ML_COMMENT ya no se define por la extensión Tokenizer. Si se configura error_reporting a E_ALL, PHP emitirá un aviso. Aunque T_ML_COMMENT no llegó a usarse, estaba definido en PHP 4. Tanto en PHP 4 y PHP 5 // y /* */ se resuelven a la constante T_COMMENT. En cualquier caso los comentarios tipo PHPDoc /** */, introducidos en PHP 5, son interpretados por PHP, y son reconocidos como T_DOC_COMMENT.
  • $_SERVER se genera con argc y argv si la directiva variables_order contiene la "S". Si se hubiera configurado el sistema explícitamente para no crear $_SERVER, entonces no se generará. El cambio se hizo para hacer que tanto argc como argv estuvieran siempre disponibles en la versión CLI independientemente del valor de la directiva variables_order. Por tanto, la versión CLI ahora siempre generará la variables globales $argc y $argv.
  • Ya no se considera a un objeto sin propiedades como "vacío".
  • En algunos casos, las clases se deben declarar antes de usarse. Sólo sucede sucede al usar algunas funcionalidades de PHP (como por ejemplo interfaces). En cualquier otro caso, se aplica el funcionamiento antiguo.
  • Ahora get_class(), get_parent_class() y get_class_methods() devuelven el nombre de las clases/métodos tal como se definieron (respetando máyúsculas) lo cual puede provocar errores en scripts antiguos que dependen de este comportamiento (se devolvían los nombres de clases/métodos en minúsculas). Una posible solución pasa por buscar estas funciones en los scripts, y emplear strtolower(). Este cambio en sensibilidad a mayúsculas también se aplica a las constantes predefinidas __CLASS__, __METHOD__, y __FUNCTION__. Se devuelven los valores exactamente como se declararon (sensible a mayúsculas).
  • ip2long() devuelve ahora FALSE cuando se proporciona una IP inválida como argumento a la función, y no -1.
  • Si hubiera funciones definidas en el fichero que se incluye, podrán usarse en el fichero principal, independientemente de si están antes o después del return. Si se incluye dos veces el mismo fichero, PHP5 emite un error fatal ya que las funciones están declaradas, mientras que PHP4 no lo hacía. Se recomienda usar include_once en su lugar para comprobar si el fichero ya se había incluido.
  • include_once y require_once en primer lugar normalizan la ruta del fichero incluido en Windows de forma que incluir A.php y a.php incluyen sólo una vez el fichero.
  • Al pasar un array por valor a una función ya no se reinicia el puntero interno del array para los acceso a éste dentro de la función. En otras palabras, en PHP 4 cuando se pasaba una array a una función, su puntero interno dentro de la función se reiniciaba, mientras que en PHP 5, cuando se pasa un array a una función, su puntero de array dentro de la función será cualesquiera fuera cuando se pasó a la función.

Ejemplo #1 strrpos() y strripos() ahora usan todo el string como cadena de búsqueda

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

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

Ejemplo #2 Ya no se considera "vacío" un objeto sin propiedades

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

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

if ($t) {
    
// Se ejecutará
}
?>

Ejemplo #3 En algunos casos, se deben definir las clases antes de usarlas

<?php

//Funciona sin errores:
$a = new a();
class 
{
}


//lanza un error:
$a = new b();

interface 
c{
}
class 
implements {


?>

add a note add a note

User Contributed Notes 13 notes

up
6
john.g
19 years ago
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.
up
5
paul at oconnor-web dot net
16 years ago
The __call function will also lowercase the method arguement:

<?php
  
function __call($method, $args) {
     if (
$method == 'Foo') {
       return
true;
     } else {
       return
false
    
}
   }
?>

(= false)
up
3
Anonymous
18 years ago
is_a have been deprecated. You can simply replace all occurences with the new instanceOf operator, although this will break backwards-compatibility with php4.
up
1
Aggelos Orfanakos
16 years ago
As with array_merge(), array_merge_recursive() returns NULL in PHP 5 if a non-array parameter is passed to it.
up
1
nami
16 years ago
addition of the note on 07-Sep-2004 06:40

if you write down your code like this PHP5 will just work fine:

<?php
     $array_1
= array('key1'=>'oranges','key2'=>'apples');
    
$array_2 = array('key3'=>'pears','key4'=>'tomatoes');
    
$array_3 = array();
    
$arr_gemerged = array_merge($array_1,$array_2,$array_3);
     echo
"result:<br>";
    
print_r($arr_gemerged);
     echo
"<br>";
?>

---

so you have to declare array_3 as array() instead of NULL
up
1
cyberhorse
19 years ago
clone() is a php function now.

if you create a subclass, it no longer uses samename methods in superclass as a constructor.
up
0
kemal djakman
16 years ago
The handling of accessing empty property of a class error has also changed:
<?php

class Foo {

    var
$Bar = 'xxx';

    function
F() {
        echo
$this->$Bar;
    }
}

$Obj = new Foo();
$Obj->F();

?>

Notice the $ sign after object dereference opr?  $Bar is empty inside method F.   PHP4 would only generate a warning, PHP5 throws a fatal error
up
0
Amir Laher
17 years ago
Some other things to be aware of:

some extra strictness:
* object members can no longer be accessed using array-member syntax
* function-calls with too many arguments will now cause errors.

Also, from PHP5.2, custom session handlers are affected:
* Best not to use global objects in custom session-handling functions. These would get destructed *before* the session is written (unless session_write_close() is called explicitly).
up
0
Anonymous
19 years ago
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.

<?php
        $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);
       
print_r($arr_gemerged);
        echo
"<br>";
?>

Result on php4:
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 /removed/by/danbrown/for/manual.php on line 7
up
-1
michael dot darmousseh at gmail dot com
14 years ago
Hack way to fix the array_merge problem so that it works with your existing php4 code

<?php
function array_merge5()
{
   
$args = func_get_args();
    foreach(
$args as $key=>$arg)
       
$args[$key] = (array) $arg;
    return
call_user_func_array("array_merge", $args);
}
?>

just put it somewhere completely accessible to your codebase and change all of your calls to array_merge to array_merge5.
up
-3
Sinured
16 years ago
Not mentioned above: The PHP/FI 2 function style (old_function aka cfunction) is no longer supported as of PHP 5.
up
-2
dward . maidencreek.com
19 years ago
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.
up
-4
Steven
16 years ago
Three more that we discovered:

== 1. No longer can re-assign $this ==

The follwoing example works under PHP4 (it outputs "OK"), but produces a fatal error under PHP5:

<?php
 
class a
 
{
    var
$text;
    function
a() { $this->text = 'OK'; }
  }

  class
b
 
{
    var
$text = 'NOT OK';
    function
b() { $this = new a(); }
  }
   
 
$myClass = new b();
  echo
$myClass->text;
?>

== 2. No comments allowed after shorthand echo block ==

The follwoing example works under PHP4, but produces a sytax error under PHP5.

<?=//comment?>

== 3. Constructors return a reference as default ==

The follwoing example works under PHP4, but produces an E_NOTICE notice under PHP5.

<?php
 
class MyClass { function MyClass() { echo('OK'); } }
 
$myObj = null;
 
$myObj &= new MyClass();
?>

Removing the ampersand solves the problem
To Top