SunshinePHP Developer Conference 2015

Cambiamenti non compatibili

Anche se la maggior parte del codice PHP 4 esistente dovrebbe funzionare senza modifiche, occorre fare attenzione ai seguenti cambiamenti incompatibili col codice precedente:

  • Ci sono alcune nuove parole chiave riservate.
  • strrpos() e strripos() ora utilizzano l'intera stringa come argomento di ricerca.
  • L'uso illegale degli offset delle stringhe causa E_ERROR invece di E_WARNING. Un esempio di utilizzo illegale è: $str = 'abc'; unset($str[0]);.
  • array_merge() è stata cambiata per accettare solo array. Se viene passata una variabile che non è un array, un E_WARNING viene lanciato per ogni parametro. Prestare attenzione, poiché il codice può cominciare ad emettere E_WARNING improvvisamente.
  • La variabile server PATH_TRANSLATED non è più impostata implicitamente sotto Apache2 SAPI diversamente che in PHP 4, dove è impostato allo stesso valore della variabile server SCRIPT_FILENAME quando non è riempito da Apache. Questa modifica è stata fatta per adeguarsi alle » specifiche CGI. Consultare il » bug #23610 per ulteriori informazioni, e vedere anche la descrizione di $_SERVER['PATH_TRANSLATED'] nel manuale. Questo problema interessa anche le versioni di PHP >= 4.3.2.
  • La costante T_ML_COMMENT non è più definita dall'estensione Tokenizer. Se error_reporting è impostata a E_ALL, PHP genera un avviso. Anche se la costante T_ML_COMMENT non è mai stata utilizzata, era definita in PHP 4. Sia in PHP 4 che in PHP 5 // e /* */ sono risolte come la costante T_COMMENT. Comunque i commenti in stile PHPDoc /** */, che a partire da PHP 5 sono analizzate da PHP, sono riconosciute come T_DOC_COMMENT.
  • $_SERVER dovrebbe essere popolata con argc e argv se variables_order include "S". Se si è configurato il sistema in modo da non creare $_SERVER, ovviamente questa non dovrebbe comparire. La modifica è stata quella di rendere argc e argv disponibile nella versione CLI a prescindere dall'impostazione di variables_order. Di conseguenza, la versione CLI ora popolerà sempre le variabili globali $argc e $argv.
  • Un oggetto senza proprietà non è più considerato "vuoto".
  • In alcuni casi le classi devono essere dichiarate prima dell'utilizzo. Questo succede solo se è usata qualcuna delle nuove caratteristiche di PHP 5 (come le interfacce). In caso contratio il comportamento è quello vecchio.
  • get_class(), get_parent_class() e get_class_methods() ora restituiscono il nome di classi/metodi come sono dichiarati (case-sensitive) il che può portare a problemi in vecchi script che si basano sul comportamento precedente (il nome di classe/metodo era sempre restituito a caratteri minuscoli). Una soluzione possibile è quella di cercare queste funzioni negli script ed utilizzare strtolower(). Questa modifica alla sensibilità di maiuscole/minuscole si applica anche alle costanti magiche predefinite __CLASS__, __METHOD__, e __FUNCTION__. I valori sono restituiti esattamente come dichiarati (case-sensitive).
  • ip2long() ora restituisce FALSE quando un IP address non valido è passata come argomento alla funzione, e non più -1.
  • Se esistono funzioni definite in un file incluso, queste possono essere utilizzate nel file principale indipendentemente dal fatto che siano prima di return o dopo. Se il file è incluso due volte, PHP 5 emette un errore fatale poiché le funzioni erano già dichiarate, mentre PHP 4 non si lamenta di questo. Si raccomanda di utilizzare include_once invece di controllare se il file è stato già incluso e fare un return condizionato all'interno del file incluso.
  • include_once e require_once in Windows per prima cosa normalizzano il percorso del file incluso in modo tale che includere A.php e a.php provochi una sola inclusione del file.

Example #1 strrpos() e strripos() ora utilizzano l'intera stringa come argomento di ricerca

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

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

Example #2 Un oggetto senza proprietà non è più considerato "vuoto"

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

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

if ($t) {
    
// Viene eseguito
}
?>

Example #3 In alcuni casi le classi devono essere dichiarate prima dell'utilizzo

<?php

//funziona senza errori:
$a = new a();
class 
{
}


//emette un errore:
$a = new b();

interface 
c{
}
class 
implements {


?>

add a note add a note

User Contributed Notes 13 notes

up
3
michael dot darmousseh at gmail dot com
4 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
2
Anonymous
8 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
2
john.g
10 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
0
paul at oconnor-web dot net
6 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
0
Aggelos Orfanakos
6 years ago
As with array_merge(), array_merge_recursive() returns NULL in PHP 5 if a non-array parameter is passed to it.
up
0
nami
7 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
0
Amir Laher
7 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
dward . maidencreek.com
9 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
0
cyberhorse
10 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
-1
Steven
6 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
up
-1
Anonymous
10 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
Sinured
7 years ago
Not mentioned above: The PHP/FI 2 function style (old_function aka cfunction) is no longer supported as of PHP 5.
up
-1
kemal djakman
7 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
To Top