PHP Unconference Europe 2015

下位互換性のない変更点

既存の PHP 5 のコードのほとんどは変更なしで動作するはずですが、 以下の下位互換性のない変更点については注意しましょう。

  • getrusage() に互換性のない引数を渡した場合に、 PHP 5.2.1 以降では NULL を返すようになりました。
  • ZipArchive::setCommentName() は、PHP 5.2.1 以降は成功した場合に TRUE を返すようになりました。
  • ZipArchive::setCommentIndex() は、PHP 5.2.1 以降は成功した場合に TRUE を返すようになりました。
  • SplFileObject::getFilename() は、PHP 5.2.1 以降ではファイルへの相対パスではなくファイル名のみを返すようになりました。
  • Win32 における環境変数 PHPRC の優先順位が変わりました。 環境変数 PHPRC は、Windows レジストリに保存されているパスより優先されるようになりました。
  • CLI SAPI は、カレントディレクトリにある php.iniphp-cli.ini を見に行かないようになりました。 明示されていませんでしたが、PHP 5.1.x では CLI バイナリが現在の作業ディレクトリにある PHP 設定ファイルを参照するようになっていました。 これは、予期せぬ設定ファイルを読み込んでしまうという問題を起こす可能性がありました。 この機能は PHP 5.2.0 で削除されました。PHP は、カレントディレクトリの php.iniphp-cli.ini を参照しません。 マニュアルの コマンドライン の部分も参照ください。
  • ゼロで割った余りを求めようとすると警告が発生するようになりました。 以前のバージョンの PHP では、integer % 0 は何も警告を発せず、 予期せぬ結果である FALSE を返していました。 PHP 5.2.0 以降では、このような操作をしようとすると E_WARNING が発生するようになりました。これは、ゼロで除算を行った際の挙動と同じです。
    <?php
    print 10 0;
    /* Warning:  Division by zero in filename on line n */
    ?>
  • __toString() が、適切な場面で常にコールされるようになりました。 マジックメソッド __toString() は、文字列コンテキストでコールされるようになりました。 つまり、オブジェクトを文字列として使用する際には常にコールされるということです。 オブジェクトを文字列として扱った場合に自動的にオブジェクト ID が返されるという機能は、PHP 5.2.0 で廃止されました。 オブジェクト ID は常に一意となるわけではないので、この機能には問題があったわけです。 この変更により、オブジェクト ID が返されることを前提としたアプリケーションは動作がおかしくなってしまいます。 オブジェクトの値を文字列として使用すると、(捕捉可能な) 致命的なエラーとなります。
    <?php
    class foo {}
    $foo = new foo;
    print 
    $foo;
    /* Catchable fatal error:  Object of class foo could
       not be converted to string in filename on line n */
    ?>
    たとえ __toString() を実装したとしても、 オブジェクトを配列のインデックスやキーとして使用することはできません。 将来的には組み込みの機能でハッシュをサポートする予定ですが、 現時点の PHP 5.2.x の段階では、自分でハッシュ処理を実装するか SPL の関数 spl_object_hash() を使用してください。 __toString() メソッド内からは例外をスローすることはできません。
    <?php
    class foo {
        public function 
    __toString() {
            throw new 
    Exception;
        }
    }

    try {
        print new 
    foo;
        
    /* Fatal error:  Method foo::__toString() must
           not throw an exception in filename on line n */
    } catch(Exception $e) {}
    ?>
  • abstract static なクラス関数が削除されました。 ちょっとした手違いで、PHP 5.0.x および 5.1.x では abstract static な関数をクラス内で定義できてしまっていました。PHP 5.2.x では、 これはインターフェイス内でのみ定義できるようになりました。
    <?php
    abstract class foo {
        abstract static function 
    bar();
        
    /* Strict Standards:  Static function foo::bar()
           should not be abstract in filename on line n */
    }
    ?>
  • Oracle 拡張モジュール を Windows で使用するには、最低でも Oracle のバージョン 10 が必要となりました。
  • RFC2397 (data: ストリーム) に対応しました。 'data' URL スキームに対応したことにより、 Windows 環境での挙動が変わる可能性があります。 NTFS ファイルシステムを使用しており、 アプリケーションでメタストリームを使用していた場合、 もし 'data:' という名前のファイルをパス情報なしでアクセスしようとすると正しく動作しません。 これを避けるには、アクセス時に 'file:' プロトコルを使用します。 » RFC 2397 も参照ください。
    <?php
    /* allow_url_include が OFF (デフォルト) の場合 */
    include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";
    /* Warning:  include(): URL file-access is disabled
       in the server configuration in filename on line n */
    ?>
  • glob() パターンの退化 バージョン 5.2.4 でのセキュリティ修正の副作用で、 "/foo/*/bar/*" 形式のパターンがうまく動作しなくなってしまっていました。 バージョン 5.2.5 以降では、glob()openbase_dir 制約に違反した場合に警告を発生させず FALSE を返すようになります。
add a note add a note

User Contributed Notes 6 notes

up
1
php dot manual at frankkleine dot de
6 years ago
Between PHP 5.2.3 and 5.2.4 another backward incompatible change was introduced: parent classes now can not access private properties of child classes with get_object_vars(). See the following example:

class Bar {
    public function dumpBar()  {
        var_dump(get_object_vars($this));
    }
}
class Foo extends Bar {
    public $public = 'public';
    protected $protected = 'protected';
    private $private = 'private';

    public function dump() {
        var_dump(get_object_vars($this));
    }
}

$foo = new Foo();
$foo->dump();
$foo->dumpBar();

The result with PHP < 5.2.4:
E:\php\tests>php get_object_vars.php
array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

And the result with PHP >= 5.2.4:
E:\php-5.2.4-Win32>php ../php/tests/get_object_vars.php
array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

array(2) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
}

As you can see the private property is missing now when dumped from the parent class Bar.
up
0
goellerk at bucks dot edu
4 years ago
str_pad has been modified as well, to enforce UPPERCASE sensitivity on the pad_type declaration.

Optional argument pad_type can be STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH. If pad_type is not specified it is assumed to be STR_PAD_RIGHT.

If entered as:
$foo = 10;
$wrong = str_pad($foo, 4,'0',str_pad_left);
print "wrong is '$wrong'<br>";

$right = str_pad($foo,4,'0',STR_PAD_LEFT);
print "right is '$right'<br>";

results:
wrong is '    '
right is '  10'
up
0
Alexander Schuch
4 years ago
If the sole reason for having "abstract static methods" is to force the implementation of such a method in a child, consider using an interface for them. The abstract class implements the interface, and a child class extends the base class and defines the "abstract static methods".

<?php
interface I
{
static public function
f();
}

abstract class
C implements I
{
// more/other methods go here
}

class
D extends C
{
static public function
f()
{
echo
'I am f().';
}
}
?>
up
0
jbarker at erepublic dot com
6 years ago
If any of your code relies on includes of URLS  à la allow_url_fopen, be aware that a new directive (allow_url_include) has been added, and that it defaults to Off.
up
0
Erik Osterman
7 years ago
It should be noted that if you provide a __toString method, you can cast the object to a string and use it as an array key (PHP 5.2.x).

e.g.   $array[ (string)$myObject ] = 'foobar';

This is an alternative to using spl_object_hash.
up
-1
Tachy
6 years ago
$string="12345";
$rightstring1=substr($string,-3);
$rightstring2=substr($string,-8);
echo "Result1: ".$rightstring1."<BR>";
echo "Result2: ".$rightstring2."<BR>";

PHP5.1.x:
Result1: 345
Result2: 12345

PHP5.2.x
Result1: 345
Result2: <Empty>
To Top