問題

程式執行出現以下錯誤

1
Fatal error: main() [<a href='function.main'>function.main</a>]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition &quot;MyClass&quot; of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in xxx.php on line 4

原因

這是因為程式某些操作產生 Incomplete Object(__PHP_Incomplete_Class),並且呼叫了此物件的函式。產生 Incomplete Object 的原因是序列化的資料轉回原始物件時,該物件的類別並未被定義,常見的情況如下:

利用 Session 存取自定義物件

例如定義一個類別

1
2
3
4
5
6
7
class MyClass
{
function f()
{
echo "Test";
}
}

存入 Session

1
2
3
4
include("c.php");
session_start();
$c = new MyClass();
$_SESSION['c'] = $c;

在別的程式取出實例

1
2
3
4
session_start();
include("c.php");
$c = $_SESSION['c'];
$c->f();

序列化與反序列化自定義物件

建立類別實例並序列化

1
2
3
include("c.php");
$c = new MyClass();
echo serialize($c); // O:1:"MyClass":0:{}

在別的程式反序列化

1
2
3
$c = unserialize('O:1:"MyClass":0:{}');
$c->f();
include("c.php");

由於在 session_start() 和反序列化之前,自定義類別並未引用,造成此錯誤。

解決方案

需引用自定義類別並且在 session_start() 和反序列化動作之前。

1
2
3
4
include("c.php");
session_start();
$c = $_SESSION['c'];
$c->f();
1
2
3
include("c.php");
$c = unserialize('O:1:"MyClass":0:{}');
$c->f();

並確保 php.ini 中的 session.auto_start 設定停用

1
session.auto_start = 0

或透過 .htaccess 停用

1
php_value session.auto_start 0