이전 버전과 호환되지 않는 변경점

기존 PHP 4 코드의 대부분은 변경 없이 작동하지만, 다음의 호환 되지 않는 변경점에는 주의해야 합니다:

  • 새 예약어가 있습니다.
  • strrpos()strripos()가 전체 문자열을 needle로 사용합니다.
  • 문자열 오프셋의 비정상적인 사용은 E_WARNING 대신 E_ERROR를 발생합니다. 비정상적인 사용의 예제: $str = 'abc'; unset($set[0]);
  • array_merge()가 배열만을 받아들이게 변경되었습니다. 배열이 아닌 값을 넘기면, 그러한 인수마다 E_WARNING을 발생합니다. 코드가 갑작스레 E_WARNING를 표시하기 시작할 수 있으므로 주의하십시오.
  • 더이상 Apahce2 SAPI에서 PATH_TRANSLATED 서버 변수를 자동으로 설정하지 않습니다. PHP 4에서는 아파치가 생성하지 않았을 때, SCRIPT_FILENAME 서버 변수와 동일하게 설정했었습니다. 이 변경은 » CGI 규격에 따르기 위한 점입니다. 자세한 정보는 » 버그 #23610를 확인하고, 매뉴얼에서 $_SERVER['PATH_TRANSLATED'] 설명을 참고하십시오. 이 내용은 PHP >= 4.3.2에도 영향이 있습니다.
  • Tokenizer 확장은 더 이상 T_ML_COMMENT 상수를 정의하지 않습니다. error_reporting을 E_ALL로 설정하면, PHP가 주의문을 생성합니다. T_ML_COMMENT는 사용되지 않았지만, PHP 4에서 정의되어 있었습니다. PHP 4와 PHP 5 둘 다, T_COMMENT 상수가 //와 /* */를 모두 인식합니다. 그러나 PHP 5에서 도입한, PHP가 처리하는 PHPDoc 스타일 주석 /** */은, T_DOC_COMMENT로 인식합니다.
  • variables_order가 "S"를 포함하고 있으면, $_SERVER는 argcargv를 가져야 합니다. 시스템이 $_SERVER를 생성하지 않게 설정하였다면, 물론 존재하지 않았습니다. 변경 후에는 variables_order 설정에 관계 없이, CLI 버전에서 argcargv를 사용할 수 있게 만듭니다. 또한, CLI 버전은 항상 전역의 $argc$argv도 가지게 되었습니다.
  • 프로퍼티가 없는 객체를 더 이상 "빈" 것으로 판단하지 않습니다.
  • 몇몇 경우에 클래스는 사용하기 전에 선언해야 합니다. 이는 PHP 5의 신기능(인터페이스 등)을 사용할 경우이며, 다른 경우엔 이전과 같습니다.
  • get_class(), get_parent_class(), get_class_methods()가 클래스/메쏘드 이름을 선언한 대로(대소문자 구분) 반환하므로, 이전의 동작(클래스/메쏘드 이름을 항상 소문자로 반환)에 의존하는 스크립트에 문제가 발생합니다. 해결법 중 하나는 모든 스크립트에서 위 함수들을 검색하여 strtolower()을 적용하는 방법입니다. 이 대소문자 구분은 마법 예약 상수 __CLASS__, __METHOD__, __FUNCTION__에도 적용됩니다. 반환되는 값은 정확히 선언한 대로(대소문자 구분) 입니다.
  • ip2long()에 잘못된 IP 주소를 인수로 넘겼을 때 이제 -1이 아닌 FALSE를 반환합니다.
  • 포함한 파일에 함수 정의가 있으면, return의 위치에 상관 없이 메인 파일에서 독립적으로 사용할 수 있습니다. 그 파일을 두번 포함하면, PHP 5는 함수가 이미 정의되어 있기에, 치명적인 오류를 발생합니다. PHP 4는 아무런 오류를 내지 않았었습니다. 포함하는 파일에서 포함 여부를 판단하고 리턴하는 대신, include_once를 사용하길 권장합니다.
  • include_oncerequire_once은 윈도우에서 포함하는 파일의 경로를 정규화해서, A.php와 a.php는 한번만 포함하게 됩니다.

Example #1 strrpos()strripos()가 전체 문자열을 needle로 사용합니다.

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

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

Example #2 프로퍼티가 없는 객체를 더 이상 "빈" 것으로 판단하지 않습니다.

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

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

if ($t) {
      
// 이 부분이 실행됩니다.
}
?>

Example #3 몇몇 경우에 클래스는 사용하기 전에 선언해야 합니다.

<?php

// 오류 없이 실행:
$a = new a();
class 
{
}


// 오류 발생:
$a = new b();

interface 
{
}
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
2
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
16 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