1--TEST-- 2serialize()/unserialize() objects 3--FILE-- 4<?php 5 6// This test verifies that old and new style (un)serializing do not interfere. 7 8function do_autoload($class_name) 9{ 10 if ($class_name != 'autoload_not_available') 11 { 12 require_once(__DIR__ . '/' . strtolower($class_name) . '.inc'); 13 } 14 echo __FUNCTION__ . "($class_name)\n"; 15} 16 17function unserializer($class_name) 18{ 19 echo __METHOD__ . "($class_name)\n"; 20 switch($class_name) 21 { 22 case 'TestNAOld': 23 eval("class TestNAOld extends TestOld {}"); 24 break; 25 case 'TestNANew': 26 eval("class TestNANew extends TestNew {}"); 27 break; 28 case 'TestNANew2': 29 eval("class TestNANew2 extends TestNew {}"); 30 break; 31 default: 32 echo "Try autoloader\n"; 33 if (!spl_autoload_functions()) { 34 spl_autoload_register(function ($class_name) { do_autoload($class_name); }); 35 } 36 spl_autoload_call($class_name); 37 break; 38 } 39} 40 41ini_set('unserialize_callback_func', 'unserializer'); 42 43class TestOld 44{ 45 function serialize() 46 { 47 echo __METHOD__ . "()\n"; 48 } 49 50 function unserialize($serialized) 51 { 52 echo __METHOD__ . "()\n"; 53 } 54 55 function __wakeup() 56 { 57 echo __METHOD__ . "()\n"; 58 } 59 60 function __sleep() 61 { 62 echo __METHOD__ . "()\n"; 63 return array(); 64 } 65} 66 67class TestNew implements Serializable 68{ 69 protected static $check = 0; 70 71 function serialize() 72 { 73 echo __METHOD__ . "()\n"; 74 switch(++self::$check) 75 { 76 case 1: 77 return NULL; 78 case 2: 79 return "2"; 80 } 81 } 82 83 function unserialize($serialized) 84 { 85 echo __METHOD__ . "()\n"; 86 } 87 88 function __wakeup() 89 { 90 echo __METHOD__ . "()\n"; 91 } 92 93 function __sleep() 94 { 95 echo __METHOD__ . "()\n"; 96 } 97} 98 99echo "===O1===\n"; 100var_dump($ser = serialize(new TestOld)); 101var_dump(unserialize($ser)); 102 103echo "===N1===\n"; 104var_dump($ser = serialize(new TestNew)); 105var_dump(unserialize($ser)); 106 107echo "===N2===\n"; 108var_dump($ser = serialize(new TestNew)); 109var_dump(unserialize($ser)); 110 111echo "===NAOld===\n"; 112var_dump(unserialize('O:9:"TestNAOld":0:{}')); 113 114echo "===NANew===\n"; 115var_dump(unserialize('O:9:"TestNANew":0:{}')); 116 117echo "===NANew2===\n"; 118var_dump(unserialize('C:10:"TestNANew2":0:{}')); 119 120echo "===AutoOld===\n"; 121var_dump(unserialize('O:19:"autoload_implements":0:{}')); 122 123// Now we have an autoloader, that will be called before the old style header. 124// If the old style handler also fails to register the class then the object 125// becomes an incomplete class instance. 126 127echo "===AutoNA===\n"; 128var_dump(unserialize('O:22:"autoload_not_available":0:{}')); 129?> 130--EXPECTF-- 131===O1=== 132TestOld::__sleep() 133string(18) "O:7:"TestOld":0:{}" 134TestOld::__wakeup() 135object(TestOld)#%d (0) { 136} 137===N1=== 138TestNew::serialize() 139string(2) "N;" 140NULL 141===N2=== 142TestNew::serialize() 143string(19) "C:7:"TestNew":1:{2}" 144TestNew::unserialize() 145object(TestNew)#%d (0) { 146} 147===NAOld=== 148unserializer(TestNAOld) 149TestOld::__wakeup() 150object(TestNAOld)#%d (0) { 151} 152===NANew=== 153unserializer(TestNANew) 154 155Warning: Erroneous data format for unserializing 'TestNANew' in %s005.php on line %d 156 157Notice: unserialize(): Error at offset 19 of 20 bytes in %s005.php on line %d 158bool(false) 159===NANew2=== 160unserializer(TestNANew2) 161TestNew::unserialize() 162object(TestNANew2)#%d (0) { 163} 164===AutoOld=== 165unserializer(autoload_implements) 166Try autoloader 167do_autoload(autoload_interface) 168do_autoload(autoload_implements) 169object(autoload_implements)#%d (0) { 170} 171===AutoNA=== 172do_autoload(autoload_not_available) 173unserializer(autoload_not_available) 174Try autoloader 175do_autoload(autoload_not_available) 176do_autoload(autoload_not_available) 177 178Warning: unserialize(): Function unserializer() hasn't defined the class it was called for in %s005.php on line %d 179object(__PHP_Incomplete_Class)#%d (1) { 180 ["__PHP_Incomplete_Class_Name"]=> 181 string(22) "autoload_not_available" 182} 183