2

エラーをスローしているエラーハンドラがあります:__PHP_Incomplete_Classを文字列に変換できませんでした。

エラーハンドラは現在、「is_object」テストを実行します。これは、「Incomplete」オブジェクトの場合は奇妙なことにfalseです。エラーハンドラを調整しようとしていますが、再シリアル化されたバージョンを解析しないと、元のクラス名を取得できません。

<?php

$o = 'O:14:"BogusTestClass":0:{}';

$c = unserialize($o);

var_dump(
    array(
        'subject' => $c,
        'is_object' => is_object($c), // false !?!?
        'get_class' => get_class($c), // __PHP_Incomplete_Class
        'gettype' => gettype($c),     // 'object'
        'Is instance of?' => $c instanceof __PHP_Incomplete_Class, // true
        'serial' => serialize($c),
    )
);    

// Tried:

var_dump($c->__PHP_Incomplete_Class_Name);
// Error:
//   The script tried to execute a method or access a property of
//   an incomplete object


$refObj = new ReflectionObject($c);
$refProp = $refObj->getProperty('__PHP_Incomplete_Class_Name');
$refProp->setAccessible(true);
var_dump($refProp->getValue($c));
// Error:
//   ReflectionProperty::getValue(): The script tried to execute a
//   method or access a property of an incomplete object.


// This works, but is fragile, since it depends on internal behavior
// of serialize
function getBadClassName($subject)
{
    $serial = serialize($subject);
    $parts  = explode(':', $serial, 4);

    if ('O' === $parts[0] && strlen($parts[2]) -2 == $parts[1]) {
        return substr($parts[2], 1, -1);
    }
    return '-- Error --';
}

var_dump(getBadClassName($c));

エラーメッセージで使用するために、不完全なオブジェクトからシリアル化されたクラスの名前を取得しようとしています。

http://pecl.php.net/package/igbinaryhttp://pecl.php.netなど、シリアル化/逆シリアル化を再定義する拡張機能を使用すると、文字列の解析が機能しなくなると推測されるため、文字列の解析を回避します。/package/APC/3.1.7apc.serializerフック。

4

2 に答える 2

5

見るべき提案に基づく

__PHP_Incomplete_Classオブジェクトプロパティへのアクセスを強制する

プロパティには、foreachおよびArrayObjectを介してアクセスできます

<?php

$array = new \ArrayObject($object);
var_dump($array['__PHP_Incomplete_Class_Name']);
于 2012-09-18T16:28:47.003 に答える
0

PHPの不完全なクラスオブジェクトを実際に操作することはできません。実際に使用できないため、オブジェクトとしてカウントされないことは私には理にかなっています。それらが存在する唯一の理由は、それらが不要なページのセッションで存続できるようにするためです。

実際に必要な場合は、オブジェクトをシリアル化解除する前に(セッション内にある場合は、前にsession_startクラスの定義を含める必要があります。エラーメッセージにはこれも書かれています。

于 2012-09-18T15:14:17.637 に答える