summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Fernandes <robinf@php.net>2008-03-18 15:11:48 +0000
committerRobin Fernandes <robinf@php.net>2008-03-18 15:11:48 +0000
commitbd9e02695154548e66ebec844c21f900f88ae7c0 (patch)
tree9c08df7769ef8fe3ba58518937d5bf0a8c7cd8c9
parent40a7a6005b23153a449fad149aca0ebb78c1c0fb (diff)
downloadphp-git-bd9e02695154548e66ebec844c21f900f88ae7c0.tar.gz
Adding more tests for serialize() and unserialize().
-rwxr-xr-xext/standard/tests/serialize/005.phpt2
-rw-r--r--ext/standard/tests/serialize/serialization_arrays_001.phpt106
-rw-r--r--ext/standard/tests/serialize/serialization_arrays_002.phpt544
-rw-r--r--ext/standard/tests/serialize/serialization_arrays_003.phpt294
-rw-r--r--ext/standard/tests/serialize/serialization_arrays_004.phpt467
-rw-r--r--ext/standard/tests/serialize/serialization_arrays_005.phpt571
-rw-r--r--ext/standard/tests/serialize/serialization_error_001.phpt42
-rw-r--r--ext/standard/tests/serialize/serialization_miscTypes_001.phptbin0 -> 7583 bytes
-rw-r--r--ext/standard/tests/serialize/serialization_objects_001.phptbin0 -> 2403 bytes
-rw-r--r--ext/standard/tests/serialize/serialization_objects_002.phptbin0 -> 7211 bytes
-rw-r--r--ext/standard/tests/serialize/serialization_objects_003.phpt67
-rw-r--r--ext/standard/tests/serialize/serialization_objects_004.phpt49
-rw-r--r--ext/standard/tests/serialize/serialization_objects_005.phpt120
-rw-r--r--ext/standard/tests/serialize/serialization_objects_006.phpt28
-rw-r--r--ext/standard/tests/serialize/serialization_objects_007.phpt42
-rw-r--r--ext/standard/tests/serialize/serialization_objects_008.phpt28
-rw-r--r--ext/standard/tests/serialize/serialization_objects_009.phpt36
-rw-r--r--ext/standard/tests/serialize/serialization_objects_010.phpt37
-rw-r--r--ext/standard/tests/serialize/serialization_objects_011.phpt196
-rw-r--r--ext/standard/tests/serialize/serialization_objects_012.phpt244
-rw-r--r--ext/standard/tests/serialize/serialization_objects_013.phpt494
-rw-r--r--ext/standard/tests/serialize/serialization_objects_014.phpt295
-rw-r--r--ext/standard/tests/serialize/serialization_objects_015.phpt532
-rw-r--r--ext/standard/tests/serialize/serialization_precision_001.phpt21
-rw-r--r--ext/standard/tests/serialize/serialization_precision_002.phpt21
-rw-r--r--ext/standard/tests/serialize/serialization_resources_001.phpt30
26 files changed, 4265 insertions, 1 deletions
diff --git a/ext/standard/tests/serialize/005.phpt b/ext/standard/tests/serialize/005.phpt
index d67f6fbf70..e7b23db701 100755
--- a/ext/standard/tests/serialize/005.phpt
+++ b/ext/standard/tests/serialize/005.phpt
@@ -179,7 +179,7 @@ do_autoload(autoload_not_available)
do_autoload(autoload_not_available)
Warning: unserialize(): Function unserializer() hasn't defined the class it was called for in %s005.php on line %d
-object(__PHP_Incomplete_Class)#1 (1) {
+object(__PHP_Incomplete_Class)#%d (1) {
["__PHP_Incomplete_Class_Name"]=>
string(22) "autoload_not_available"
}
diff --git a/ext/standard/tests/serialize/serialization_arrays_001.phpt b/ext/standard/tests/serialize/serialization_arrays_001.phpt
new file mode 100644
index 0000000000..f62f698554
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_arrays_001.phpt
@@ -0,0 +1,106 @@
+--TEST--
+Test serialize() & unserialize() functions: arrays (circular references)
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+echo "\n--- Testing Circular reference of an array ---\n";
+
+echo "-- Normal array --\n";
+$arr_circ = array(0, 1, -2, 3.333333, "a", array(), &$arr_circ);
+$serialize_data = serialize($arr_circ);
+var_dump( $serialize_data );
+$arr_circ = unserialize($serialize_data);
+var_dump( $arr_circ );
+
+echo "\n-- Associative array --\n";
+$arr_asso = array("a" => "test");
+$arr_asso[ "b" ] = &$arr_asso[ "a" ];
+var_dump($arr_asso);
+$serialize_data = serialize($arr_asso);
+var_dump($serialize_data);
+$arr_asso = unserialize($serialize_data);
+var_dump($arr_asso);
+
+echo "\nDone";
+?>
+--EXPECTF--
+
+--- Testing Circular reference of an array ---
+-- Normal array --
+string(238) "a:7:{i:0;i:0;i:1;i:1;i:2;i:-2;i:3;d:3.333333000000000101437080957111902534961700439453125;i:4;s:1:"a";i:5;a:0:{}i:6;a:7:{i:0;i:0;i:1;i:1;i:2;i:-2;i:3;d:3.333333000000000101437080957111902534961700439453125;i:4;s:1:"a";i:5;a:0:{}i:6;R:8;}}"
+array(7) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(-2)
+ [3]=>
+ float(3.333333)
+ [4]=>
+ string(1) "a"
+ [5]=>
+ array(0) {
+ }
+ [6]=>
+ &array(7) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(-2)
+ [3]=>
+ float(3.333333)
+ [4]=>
+ string(1) "a"
+ [5]=>
+ array(0) {
+ }
+ [6]=>
+ &array(7) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(-2)
+ [3]=>
+ float(3.333333)
+ [4]=>
+ string(1) "a"
+ [5]=>
+ array(0) {
+ }
+ [6]=>
+ *RECURSION*
+ }
+ }
+}
+
+-- Associative array --
+array(2) {
+ ["a"]=>
+ &string(4) "test"
+ ["b"]=>
+ &string(4) "test"
+}
+string(37) "a:2:{s:1:"a";s:4:"test";s:1:"b";R:2;}"
+array(2) {
+ ["a"]=>
+ &string(4) "test"
+ ["b"]=>
+ &string(4) "test"
+}
+
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_002.phpt b/ext/standard/tests/serialize/serialization_arrays_002.phpt
new file mode 100644
index 0000000000..f8cef7818e
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_arrays_002.phpt
@@ -0,0 +1,544 @@
+--TEST--
+serialization: arrays with references amonst elements
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$a) {
+ var_dump($a);
+ $ser = serialize($a);
+ var_dump($ser);
+
+ $b = unserialize($ser);
+ var_dump($b);
+ $b[0] = "b0.changed";
+ var_dump($b);
+ $b[1] = "b1.changed";
+ var_dump($b);
+ $b[2] = "b2.changed";
+ var_dump($b);
+}
+
+echo "\n\n--- No references:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0 refs 1:\n";
+$a = array();
+$a[0] = &$a[1];
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0 refs 2:\n";
+$a = array();
+$a[0] = &$a[2];
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[0];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs 2:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[2];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 2 refs 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$a[0];
+check($a);
+
+echo "\n\n--- 2 refs 1:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$a[1];
+check($a);
+
+echo "\n\n--- 0,1 ref 2:\n";
+$a = array();
+$a[0] = &$a[2];
+$a[1] = &$a[2];
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 0,2 ref 1:\n";
+$a = array();
+$a[0] = &$a[1];
+$a[1] = 1;
+$a[2] = &$a[1];
+check($a);
+
+echo "\n\n--- 1,2 ref 0:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = &$a[0];
+$a[2] = &$a[0];
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- No references:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 0 refs 1:
+array(3) {
+ [1]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:1;i:1;i:0;R:2;i:2;i:1;}"
+array(3) {
+ [1]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [1]=>
+ &string(10) "b0.changed"
+ [0]=>
+ &string(10) "b0.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [1]=>
+ &string(10) "b1.changed"
+ [0]=>
+ &string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [1]=>
+ &string(10) "b1.changed"
+ [0]=>
+ &string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 0 refs 2:
+array(3) {
+ [2]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+}
+string(30) "a:3:{i:2;i:1;i:0;R:2;i:1;i:1;}"
+array(3) {
+ [2]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+}
+array(3) {
+ [2]=>
+ &string(10) "b0.changed"
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ int(1)
+}
+array(3) {
+ [2]=>
+ &string(10) "b0.changed"
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+}
+array(3) {
+ [2]=>
+ &string(10) "b2.changed"
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ string(10) "b1.changed"
+}
+
+
+--- 1 refs 0:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;i:1;}"
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1 refs 2:
+array(3) {
+ [0]=>
+ int(1)
+ [2]=>
+ &int(1)
+ [1]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:2;i:1;i:1;R:3;}"
+array(3) {
+ [0]=>
+ int(1)
+ [2]=>
+ &int(1)
+ [1]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [2]=>
+ &int(1)
+ [1]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [2]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [2]=>
+ &string(10) "b2.changed"
+ [1]=>
+ &string(10) "b2.changed"
+}
+
+
+--- 2 refs 0:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;R:2;}"
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+
+
+--- 2 refs 1:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;R:3;}"
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &string(10) "b2.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+
+
+--- 0,1 ref 2:
+array(3) {
+ [2]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+}
+string(30) "a:3:{i:2;i:1;i:0;R:2;i:1;R:2;}"
+array(3) {
+ [2]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+}
+array(3) {
+ [2]=>
+ &string(10) "b0.changed"
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [2]=>
+ &string(10) "b1.changed"
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [2]=>
+ &string(10) "b2.changed"
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ &string(10) "b2.changed"
+}
+
+
+--- 0,2 ref 1:
+array(3) {
+ [1]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:1;i:1;i:0;R:2;i:2;R:2;}"
+array(3) {
+ [1]=>
+ &int(1)
+ [0]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [1]=>
+ &string(10) "b0.changed"
+ [0]=>
+ &string(10) "b0.changed"
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [1]=>
+ &string(10) "b1.changed"
+ [0]=>
+ &string(10) "b1.changed"
+ [2]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [1]=>
+ &string(10) "b2.changed"
+ [0]=>
+ &string(10) "b2.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+
+
+--- 1,2 ref 0:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;R:2;}"
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ &string(10) "b2.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_003.phpt b/ext/standard/tests/serialize/serialization_arrays_003.phpt
new file mode 100644
index 0000000000..8d664fccf3
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_arrays_003.phpt
@@ -0,0 +1,294 @@
+--TEST--
+serialization: arrays with references to an external variable
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$a) {
+ var_dump($a);
+ $ser = serialize($a);
+ var_dump($ser);
+
+ $b = unserialize($ser);
+ var_dump($b);
+ $b[0] = "b0.changed";
+ var_dump($b);
+ $b[1] = "b1.changed";
+ var_dump($b);
+ $b[2] = "b2.changed";
+ var_dump($b);
+}
+
+echo "\n\n--- 0 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = 1;
+$a[1] = &$ext;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 2 refs external:\n";
+$ext = 1;
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$a[2] = &$ext;
+check($a);
+
+echo "\n\n--- 1,2 ref external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = &$ext;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2,3 ref external:\n";
+$ext = 1;
+$a = array();
+$a[0] = &$ext;
+$a[1] = &$ext;
+$a[2] = &$ext;
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- 0 refs external:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1 refs external:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 2 refs external:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;i:1;i:2;i:1;}"
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1,2 ref external:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;i:1;}"
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1,2,3 ref external:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+string(30) "a:3:{i:0;i:1;i:1;R:2;i:2;R:2;}"
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ &string(10) "b2.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_004.phpt b/ext/standard/tests/serialize/serialization_arrays_004.phpt
new file mode 100644
index 0000000000..942afdfb93
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_arrays_004.phpt
@@ -0,0 +1,467 @@
+--TEST--
+serialization: arrays with references to the containing array
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$a) {
+ var_dump($a);
+ $ser = serialize($a);
+ var_dump($ser);
+
+ $b = unserialize($ser);
+ var_dump($b);
+ $b[0] = "b0.changed";
+ var_dump($b);
+ $b[1] = "b1.changed";
+ var_dump($b);
+ $b[2] = "b2.changed";
+ var_dump($b);
+}
+
+echo "\n\n--- 1 refs container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = 1;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2 ref container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = &$a;
+$a[2] = 1;
+check($a);
+
+echo "\n\n--- 1,2,3 ref container:\n";
+$a = array();
+$a[0] = &$a;
+$a[1] = &$a;
+$a[2] = &$a;
+check($a);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+--- 1 refs container:
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;i:1;i:2;i:1;}i:1;i:1;i:2;i:1;}"
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ %string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ %string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ %string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1,2 ref container:
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;R:2;i:2;i:1;}i:1;R:2;i:2;i:1;}"
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+ }
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- 1,2,3 ref container:
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+}
+string(56) "a:3:{i:0;a:3:{i:0;R:2;i:1;R:2;i:2;R:2;}i:1;R:2;i:2;R:2;}"
+array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [1]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ [2]=>
+ &array(3) {
+ [0]=>
+ *RECURSION*
+ [1]=>
+ *RECURSION*
+ [2]=>
+ *RECURSION*
+ }
+ }
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ [2]=>
+ &string(10) "b0.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ &string(10) "b1.changed"
+}
+array(3) {
+ [0]=>
+ &string(10) "b2.changed"
+ [1]=>
+ &string(10) "b2.changed"
+ [2]=>
+ &string(10) "b2.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_arrays_005.phpt b/ext/standard/tests/serialize/serialization_arrays_005.phpt
new file mode 100644
index 0000000000..dd3e436edd
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_arrays_005.phpt
@@ -0,0 +1,571 @@
+--TEST--
+serialization: arrays with references, nested
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$a) {
+ var_dump($a);
+ $ser = serialize($a);
+ var_dump($ser);
+
+ $b = unserialize($ser);
+
+ // Change each element and dump result.
+ foreach($b as $k=>$v) {
+ if (is_array($v)){
+ foreach($b[$k] as $sk=>$sv) {
+ $b[$k][$sk] = "b$k.$sk.changed";
+ var_dump($b);
+ }
+ } else {
+ $b[$k] = "b$k.changed";
+ var_dump($b);
+ }
+ }
+}
+
+echo "\n\n--- Nested array references 1 element in containing array:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = &$c[0];
+$a[1] = 1;
+check($c);
+
+echo "\n\n--- Nested array references 1 element in containing array (slightly different):\n";
+$a = array();
+$c = array(1,&$a,1);
+$a[0] = 1;
+$a[1] = &$c[0];
+check($c);
+
+echo "\n\n--- Nested array references 2 elements in containing array:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = &$c[0];
+$a[1] = &$c[1];
+check($c);
+
+
+echo "\n\n--- Containing array references 1 element in nested array:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$c = array(1,&$a[0],&$a);
+check($c);
+
+echo "\n\n--- Containing array references 2 elements in nested array:\n";
+$a = array();
+$a[0] = 1;
+$a[1] = 1;
+$c = array(&$a[0],&$a[1],&$a);
+check($c);
+
+echo "\n\n--- Nested array references container:\n";
+$a = array();
+$c = array(1,1,&$a);
+$a[0] = 1;
+$a[1] = &$c;
+check($c);
+
+?>
+--EXPECTF--
+
+
+--- Nested array references 1 element in containing array:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;i:1;}}"
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ string(12) "b2.1.changed"
+ }
+}
+
+
+--- Nested array references 1 element in containing array (slightly different):
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ &int(1)
+ }
+ [2]=>
+ int(1)
+}
+string(48) "a:3:{i:0;i:1;i:1;a:2:{i:0;i:1;i:1;R:2;}i:2;i:1;}"
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ &string(10) "b0.changed"
+ }
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ array(2) {
+ [0]=>
+ string(12) "b1.0.changed"
+ [1]=>
+ &string(10) "b0.changed"
+ }
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(12) "b1.1.changed"
+ [1]=>
+ array(2) {
+ [0]=>
+ string(12) "b1.0.changed"
+ [1]=>
+ &string(12) "b1.1.changed"
+ }
+ [2]=>
+ int(1)
+}
+array(3) {
+ [0]=>
+ &string(12) "b1.1.changed"
+ [1]=>
+ array(2) {
+ [0]=>
+ string(12) "b1.0.changed"
+ [1]=>
+ &string(12) "b1.1.changed"
+ }
+ [2]=>
+ string(10) "b2.changed"
+}
+
+
+--- Nested array references 2 elements in containing array:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;R:3;}}"
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ }
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(12) "b2.1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(12) "b2.1.changed"
+ }
+}
+
+
+--- Containing array references 1 element in nested array:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:3;i:1;i:1;}}"
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ [2]=>
+ array(2) {
+ [0]=>
+ &int(1)
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b1.changed"
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &string(12) "b2.0.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ int(1)
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ &string(12) "b2.0.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ string(12) "b2.1.changed"
+ }
+}
+
+
+--- Containing array references 2 elements in nested array:
+array(3) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ &int(1)
+ [1]=>
+ &int(1)
+ }
+}
+string(48) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;R:2;i:1;R:3;}}"
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &int(1)
+ }
+}
+array(3) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(10) "b0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(10) "b1.changed"
+ }
+}
+array(3) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(12) "b2.1.changed"
+ [2]=>
+ array(2) {
+ [0]=>
+ &string(12) "b2.0.changed"
+ [1]=>
+ &string(12) "b2.1.changed"
+ }
+}
+
+
+--- Nested array references container:
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ &array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ &array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ *RECURSION*
+ }
+ }
+ }
+ }
+}
+string(74) "a:3:{i:0;i:1;i:1;i:1;i:2;a:2:{i:0;i:1;i:1;a:3:{i:0;i:1;i:1;i:1;i:2;R:4;}}}"
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ *RECURSION*
+ }
+ }
+ }
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ *RECURSION*
+ }
+ }
+ }
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ &array(2) {
+ [0]=>
+ string(12) "b2.0.changed"
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ &array(2) {
+ [0]=>
+ string(12) "b2.0.changed"
+ [1]=>
+ array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(1)
+ [2]=>
+ *RECURSION*
+ }
+ }
+ }
+ }
+}
+array(3) {
+ [0]=>
+ string(10) "b0.changed"
+ [1]=>
+ string(10) "b1.changed"
+ [2]=>
+ &array(2) {
+ [0]=>
+ string(12) "b2.0.changed"
+ [1]=>
+ string(12) "b2.1.changed"
+ }
+}
diff --git a/ext/standard/tests/serialize/serialization_error_001.phpt b/ext/standard/tests/serialize/serialization_error_001.phpt
new file mode 100644
index 0000000000..3f530580d6
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_error_001.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Test serialize() & unserialize() functions: error conditions - wrong number of args.
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+echo "*** Testing serialize()/unserialize() : error conditions ***\n";
+
+// Zero arguments
+var_dump( serialize() );
+var_dump( unserialize() );
+
+//Test serialize with one more than the expected number of arguments
+var_dump( serialize(1,2) );
+var_dump( unserialize(1,2) );
+
+echo "Done";
+?>
+--EXPECTF--
+*** Testing serialize()/unserialize() : error conditions ***
+
+Warning: Wrong parameter count for serialize() in %s on line 16
+NULL
+
+Warning: unserialize() expects exactly 1 parameter, 0 given in %s on line 17
+bool(false)
+
+Warning: Wrong parameter count for serialize() in %s on line 20
+NULL
+
+Warning: unserialize() expects exactly 1 parameter, 2 given in %s on line 21
+bool(false)
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_miscTypes_001.phpt b/ext/standard/tests/serialize/serialization_miscTypes_001.phpt
new file mode 100644
index 0000000000..c38b0bbe23
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_miscTypes_001.phpt
Binary files differ
diff --git a/ext/standard/tests/serialize/serialization_objects_001.phpt b/ext/standard/tests/serialize/serialization_objects_001.phpt
new file mode 100644
index 0000000000..aafb26629f
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_001.phpt
Binary files differ
diff --git a/ext/standard/tests/serialize/serialization_objects_002.phpt b/ext/standard/tests/serialize/serialization_objects_002.phpt
new file mode 100644
index 0000000000..95c2dfb681
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_002.phpt
Binary files differ
diff --git a/ext/standard/tests/serialize/serialization_objects_003.phpt b/ext/standard/tests/serialize/serialization_objects_003.phpt
new file mode 100644
index 0000000000..c20590b797
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_003.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Test serialize() & unserialize() functions: objects (abstract classes)
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+echo "\n--- Testing Abstract Class ---\n";
+// abstract class
+abstract class Name
+{
+ public function Name() {
+ $this->a = 10;
+ $this->b = 12.222;
+ $this->c = "string";
+ }
+ abstract protected function getClassName();
+ public function printClassName () {
+ return $this->getClassName();
+ }
+}
+// implement abstract class
+class extendName extends Name
+{
+ var $a, $b, $c;
+
+ protected function getClassName() {
+ return "extendName";
+ }
+}
+
+$obj_extendName = new extendName();
+$serialize_data = serialize($obj_extendName);
+var_dump( $serialize_data );
+$unserialize_data = unserialize($serialize_data);
+var_dump( $unserialize_data );
+
+$serialize_data = serialize($obj_extendName->printClassName());
+var_dump( $serialize_data );
+$unserialize_data = unserialize($serialize_data);
+var_dump( $unserialize_data );
+
+echo "\nDone";
+?>
+--EXPECTF--
+--- Testing Abstract Class ---
+string(119) "O:10:"extendName":3:{s:1:"a";i:10;s:1:"b";d:12.2219999999999995310417943983338773250579833984375;s:1:"c";s:6:"string";}"
+object(extendName)#%d (3) {
+ ["a"]=>
+ int(10)
+ ["b"]=>
+ float(12.222)
+ ["c"]=>
+ string(6) "string"
+}
+string(18) "s:10:"extendName";"
+string(10) "extendName"
+
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_004.phpt b/ext/standard/tests/serialize/serialization_objects_004.phpt
new file mode 100644
index 0000000000..6b826a398b
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_004.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Test serialize() & unserialize() functions: objects - ensure that COW references of objects are not serialized separately (unlike other types).
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+$x = new stdClass;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = 1;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = "a";
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = true;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = null;
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+$x = array();
+$ref = &$x;
+var_dump(serialize(array($x, $x)));
+
+echo "Done";
+?>
+--EXPECTF--
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}"
+string(22) "a:2:{i:0;i:1;i:1;i:1;}"
+string(30) "a:2:{i:0;s:1:"a";i:1;s:1:"a";}"
+string(22) "a:2:{i:0;b:1;i:1;b:1;}"
+string(18) "a:2:{i:0;N;i:1;N;}"
+string(26) "a:2:{i:0;a:0:{}i:1;a:0:{}}"
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_005.phpt b/ext/standard/tests/serialize/serialization_objects_005.phpt
new file mode 100644
index 0000000000..35b1593879
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_005.phpt
@@ -0,0 +1,120 @@
+--TEST--
+Check behaviour of incomplete class
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+$serialized = 'O:1:"C":1:{s:1:"p";i:1;}';
+
+$incomplete = unserialize($serialized);
+eval('Class C {}');
+$complete = unserialize($serialized);
+
+
+echo "\n\n---> Various types of access on complete class:\n" ;
+var_dump($complete);
+var_dump(is_object($complete));
+var_dump($complete->p);
+
+$ref1 = "ref1.original";
+$complete->p = &$ref1;
+var_dump($complete->p);
+$ref1 = "ref1.changed";
+var_dump($complete->p);
+$complete->p = "p.changed";
+var_dump($ref1);
+
+var_dump(isset($complete->x));
+$complete->x = "x.new";
+var_dump(isset($complete->x));
+unset($complete->x);
+var_dump($complete->x);
+
+
+echo "\n\n---> Same types of access on incomplete class:\n" ;
+var_dump($incomplete);
+var_dump(is_object($incomplete));
+var_dump($incomplete->p);
+
+$ref2 = "ref1.original";
+$incomplete->p = &$ref2;
+var_dump($incomplete->p);
+$ref2 = "ref1.changed";
+var_dump($incomplete->p);
+$incomplete->p = "p.changed";
+var_dump($ref1);
+
+var_dump(isset($incomplete->x));
+$incomplete->x = "x.new";
+var_dump(isset($incomplete->x));
+unset($incomplete->x);
+var_dump($incomplete->x);
+
+$incomplete->f();
+
+echo "Done";
+?>
+--EXPECTF--
+---> Various types of access on complete class:
+object(C)#%d (1) {
+ ["p"]=>
+ int(1)
+}
+bool(true)
+int(1)
+string(13) "ref1.original"
+string(12) "ref1.changed"
+string(9) "p.changed"
+bool(false)
+bool(true)
+
+Notice: Undefined property: C::$x in %s on line 37
+NULL
+
+
+---> Same types of access on incomplete class:
+object(__PHP_Incomplete_Class)#%d (2) {
+ ["__PHP_Incomplete_Class_Name"]=>
+ string(1) "C"
+ ["p"]=>
+ int(1)
+}
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 43
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 46
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 47
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 49
+NULL
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 50
+string(9) "p.changed"
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 53
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 54
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 55
+bool(false)
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 56
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 57
+NULL
+
+Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" 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 %s on line 59 \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_006.phpt b/ext/standard/tests/serialize/serialization_objects_006.phpt
new file mode 100644
index 0000000000..e223f4ee12
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_006.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Behaviour of incomplete class is preserved even when it was not created by unserialize().
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+$a = new __PHP_Incomplete_Class;
+var_dump($a);
+var_dump($a->p);
+
+echo "Done";
+?>
+--EXPECTF--
+object(__PHP_Incomplete_Class)#%d (0) {
+}
+
+Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "unknown" 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 %s on line 15
+NULL
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_007.phpt b/ext/standard/tests/serialize/serialization_objects_007.phpt
new file mode 100644
index 0000000000..9cba9d13b5
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_007.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Ensure __autoload is called twice if unserialize_callback_func is defined.
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function __autoload($name) {
+ echo "in __autoload($name)\n";
+}
+
+ini_set('unserialize_callback_func','check');
+
+function check($name) {
+ echo "in check($name)\n";
+}
+
+$o = unserialize('O:3:"FOO":0:{}');
+
+var_dump($o);
+
+echo "Done";
+?>
+--EXPECTF--
+in __autoload(FOO)
+in check(FOO)
+in __autoload(FOO)
+
+Warning: unserialize(): Function check() hasn't defined the class it was called for in %s on line 23
+object(__PHP_Incomplete_Class)#%d (1) {
+ ["__PHP_Incomplete_Class_Name"]=>
+ string(3) "FOO"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_008.phpt b/ext/standard/tests/serialize/serialization_objects_008.phpt
new file mode 100644
index 0000000000..b963872f28
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_008.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bad unserialize_callback_func
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+ini_set('unserialize_callback_func','Nonexistent');
+$o = unserialize('O:3:"FOO":0:{}');
+var_dump($o);
+echo "Done";
+?>
+--EXPECTF--
+
+Warning: unserialize(): defined (Nonexistent) but not found in %s on line 14
+object(__PHP_Incomplete_Class)#%d (1) {
+ ["__PHP_Incomplete_Class_Name"]=>
+ string(3) "FOO"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_009.phpt b/ext/standard/tests/serialize/serialization_objects_009.phpt
new file mode 100644
index 0000000000..2e8b2dc80f
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_009.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Custom unserialization of classes with no custom unserializer.
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+$ser = 'C:1:"C":6:{dasdas}';
+$a = unserialize($ser);
+eval('class C {}');
+$b = unserialize($ser);
+
+var_dump($a, $b);
+
+echo "Done";
+?>
+--EXPECTF--
+
+Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line 14
+
+Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 14
+
+Warning: Class C has no unserializer in %s on line 16
+
+Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 16
+bool(false)
+bool(false)
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_010.phpt b/ext/standard/tests/serialize/serialization_objects_010.phpt
new file mode 100644
index 0000000000..0fbf0723df
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_010.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Serialize() must return a string or NULL
+--SKIPIF--
+<?php if (!interface_exists('Serializable')) die('skip Interface Serialzable not defined'); ?>
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+Class C implements Serializable {
+ public function serialize() {
+ return $this;
+ }
+
+ public function unserialize($blah) {
+ }
+}
+
+try {
+ var_dump(serialize(new C));
+} catch (Exception $e) {
+ echo $e->getMessage(). "\n";
+}
+
+echo "Done";
+?>
+--EXPECTF--
+C::serialize() must return a string or NULL
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_011.phpt b/ext/standard/tests/serialize/serialization_objects_011.phpt
new file mode 100644
index 0000000000..1dc48390c2
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_011.phpt
@@ -0,0 +1,196 @@
+--TEST--
+Object serialization / unserialization with inherited and hidden properties.
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+Class A {
+ private $APriv = "A.APriv";
+ protected $AProt = "A.AProt";
+ public $APub = "A.APub";
+
+ function audit() {
+ return isset($this->APriv, $this->AProt, $this->APub);
+ }
+}
+
+Class B extends A {
+ private $BPriv = "B.BPriv";
+ protected $BProt = "B.BProt";
+ public $BPub = "B.BPub";
+
+ function audit() {
+ return parent::audit() && isset($this->AProt, $this->APub,
+ $this->BPriv, $this->BProt, $this->BPub);
+ }
+}
+
+Class C extends B {
+ private $APriv = "C.APriv";
+ protected $AProt = "C.AProt";
+ public $APub = "C.APub";
+
+ private $CPriv = "C.CPriv";
+ protected $CProt = "C.BProt";
+ public $CPub = "C.CPub";
+
+ function audit() {
+ return parent::audit() && isset($this->APriv, $this->AProt, $this->APub,
+ $this->BProt, $this->BPub,
+ $this->CPriv, $this->CProt, $this->CPub);
+ }
+}
+
+function prettyPrint($obj) {
+ echo "\n\nBefore serialization:\n";
+ var_dump($obj);
+
+ echo "Serialized form:\n";
+ $ser = serialize($obj);
+ $serPrintable = str_replace("\0", '\0', $ser);
+ var_dump($serPrintable);
+
+ echo "Unserialized:\n";
+ $uobj = unserialize($ser);
+ var_dump($uobj);
+
+ echo "Sanity check: ";
+ var_dump($uobj->audit());
+}
+
+echo "-- Test instance of A --\n";
+prettyPrint(new A);
+echo "\n\n-- Test instance of B --\n";
+prettyPrint(new B);
+echo "\n\n-- Test instance of C --\n";
+prettyPrint(new C);
+
+echo "Done";
+?>
+--EXPECTF--
+-- Test instance of A --
+
+
+Before serialization:
+object(A)#%d (3) {
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+ ["AProt":protected]=>
+ string(7) "A.AProt"
+ ["APub"]=>
+ string(6) "A.APub"
+}
+Serialized form:
+string(98) "O:1:"A":3:{s:8:"\0A\0APriv";s:7:"A.APriv";s:8:"\0*\0AProt";s:7:"A.AProt";s:4:"APub";s:6:"A.APub";}"
+Unserialized:
+object(A)#%d (3) {
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+ ["AProt":protected]=>
+ string(7) "A.AProt"
+ ["APub"]=>
+ string(6) "A.APub"
+}
+Sanity check: bool(true)
+
+
+-- Test instance of B --
+
+
+Before serialization:
+object(B)#%d (6) {
+ ["BPriv":"B":private]=>
+ string(7) "B.BPriv"
+ ["BProt":protected]=>
+ string(7) "B.BProt"
+ ["BPub"]=>
+ string(6) "B.BPub"
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+ ["AProt":protected]=>
+ string(7) "A.AProt"
+ ["APub"]=>
+ string(6) "A.APub"
+}
+Serialized form:
+string(184) "O:1:"B":6:{s:8:"\0B\0BPriv";s:7:"B.BPriv";s:8:"\0*\0BProt";s:7:"B.BProt";s:4:"BPub";s:6:"B.BPub";s:8:"\0A\0APriv";s:7:"A.APriv";s:8:"\0*\0AProt";s:7:"A.AProt";s:4:"APub";s:6:"A.APub";}"
+Unserialized:
+object(B)#%d (6) {
+ ["BPriv":"B":private]=>
+ string(7) "B.BPriv"
+ ["BProt":protected]=>
+ string(7) "B.BProt"
+ ["BPub"]=>
+ string(6) "B.BPub"
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+ ["AProt":protected]=>
+ string(7) "A.AProt"
+ ["APub"]=>
+ string(6) "A.APub"
+}
+Sanity check: bool(true)
+
+
+-- Test instance of C --
+
+
+Before serialization:
+object(C)#%d (10) {
+ ["APriv":"C":private]=>
+ string(7) "C.APriv"
+ ["AProt":protected]=>
+ string(7) "C.AProt"
+ ["APub"]=>
+ string(6) "C.APub"
+ ["CPriv":"C":private]=>
+ string(7) "C.CPriv"
+ ["CProt":protected]=>
+ string(7) "C.BProt"
+ ["CPub"]=>
+ string(6) "C.CPub"
+ ["BPriv":"B":private]=>
+ string(7) "B.BPriv"
+ ["BProt":protected]=>
+ string(7) "B.BProt"
+ ["BPub"]=>
+ string(6) "B.BPub"
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+}
+Serialized form:
+string(302) "O:1:"C":10:{s:8:"\0C\0APriv";s:7:"C.APriv";s:8:"\0*\0AProt";s:7:"C.AProt";s:4:"APub";s:6:"C.APub";s:8:"\0C\0CPriv";s:7:"C.CPriv";s:8:"\0*\0CProt";s:7:"C.BProt";s:4:"CPub";s:6:"C.CPub";s:8:"\0B\0BPriv";s:7:"B.BPriv";s:8:"\0*\0BProt";s:7:"B.BProt";s:4:"BPub";s:6:"B.BPub";s:8:"\0A\0APriv";s:7:"A.APriv";}"
+Unserialized:
+object(C)#%d (10) {
+ ["APriv":"C":private]=>
+ string(7) "C.APriv"
+ ["AProt":protected]=>
+ string(7) "C.AProt"
+ ["APub"]=>
+ string(6) "C.APub"
+ ["CPriv":"C":private]=>
+ string(7) "C.CPriv"
+ ["CProt":protected]=>
+ string(7) "C.BProt"
+ ["CPub"]=>
+ string(6) "C.CPub"
+ ["BPriv":"B":private]=>
+ string(7) "B.BPriv"
+ ["BProt":protected]=>
+ string(7) "B.BProt"
+ ["BPub"]=>
+ string(6) "B.BPub"
+ ["APriv":"A":private]=>
+ string(7) "A.APriv"
+}
+Sanity check: bool(true)
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_012.phpt b/ext/standard/tests/serialize/serialization_objects_012.phpt
new file mode 100644
index 0000000000..f994d8e260
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_012.phpt
@@ -0,0 +1,244 @@
+--TEST--
+Object serialization / unserialization: real references and COW references
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+echo "\n\nArray containing same object twice:\n";
+$obj = new stdclass;
+$a[0] = $obj;
+$a[1] = $a[0];
+var_dump($a);
+
+$ser = serialize($a);
+var_dump($ser);
+
+$ua = unserialize($ser);
+var_dump($ua);
+$ua[0]->a = "newProp";
+var_dump($ua);
+$ua[0] = "a0.changed";
+var_dump($ua);
+
+
+echo "\n\nArray containing object and reference to that object:\n";
+$obj = new stdclass;
+$a[0] = $obj;
+$a[1] = &$a[0];
+var_dump($a);
+
+$ser = serialize($a);
+var_dump($ser);
+
+$ua = unserialize($ser);
+var_dump($ua);
+$ua[0]->a = "newProp";
+var_dump($ua);
+$ua[0] = "a0.changed";
+var_dump($ua);
+
+echo "\n\nObject containing same object twice:";
+$obj = new stdclass;
+$contaner = new stdclass;
+$contaner->a = $obj;
+$contaner->b = $contaner->a;
+var_dump($contaner);
+
+$ser = serialize($contaner);
+var_dump($ser);
+
+$ucontainer = unserialize($ser);
+var_dump($ucontainer);
+$ucontainer->a->a = "newProp";
+var_dump($ucontainer);
+$ucontainer->a = "container->a.changed";
+var_dump($ucontainer);
+
+
+echo "\n\nObject containing object and reference to that object:\n";
+$obj = new stdclass;
+$contaner = new stdclass;
+$contaner->a = $obj;
+$contaner->b = &$contaner->a;
+var_dump($contaner);
+
+$ser = serialize($contaner);
+var_dump($ser);
+
+$ucontainer = unserialize($ser);
+var_dump($ucontainer);
+$ucontainer->a->a = "newProp";
+var_dump($ucontainer);
+$ucontainer->b = "container->a.changed";
+var_dump($ucontainer);
+
+echo "Done";
+?>
+--EXPECTF--
+
+
+Array containing same object twice:
+array(2) {
+ [0]=>
+ object(stdClass)#%d (0) {
+ }
+ [1]=>
+ object(stdClass)#%d (0) {
+ }
+}
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}"
+array(2) {
+ [0]=>
+ object(stdClass)#%d (0) {
+ }
+ [1]=>
+ object(stdClass)#%d (0) {
+ }
+}
+array(2) {
+ [0]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+ [1]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+array(2) {
+ [0]=>
+ string(10) "a0.changed"
+ [1]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+
+
+Array containing object and reference to that object:
+array(2) {
+ [0]=>
+ &object(stdClass)#%d (0) {
+ }
+ [1]=>
+ &object(stdClass)#%d (0) {
+ }
+}
+string(37) "a:2:{i:0;O:8:"stdClass":0:{}i:1;R:2;}"
+array(2) {
+ [0]=>
+ &object(stdClass)#%d (0) {
+ }
+ [1]=>
+ &object(stdClass)#%d (0) {
+ }
+}
+array(2) {
+ [0]=>
+ &object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+ [1]=>
+ &object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+array(2) {
+ [0]=>
+ &string(10) "a0.changed"
+ [1]=>
+ &string(10) "a0.changed"
+}
+
+
+Object containing same object twice:object(stdClass)#%d (2) {
+ ["a"]=>
+ object(stdClass)#%d (0) {
+ }
+ ["b"]=>
+ object(stdClass)#%d (0) {
+ }
+}
+string(58) "O:8:"stdClass":2:{s:1:"a";O:8:"stdClass":0:{}s:1:"b";r:2;}"
+object(stdClass)#%d (2) {
+ ["a"]=>
+ object(stdClass)#%d (0) {
+ }
+ ["b"]=>
+ object(stdClass)#%d (0) {
+ }
+}
+object(stdClass)#%d (2) {
+ ["a"]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+ ["b"]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+object(stdClass)#%d (2) {
+ ["a"]=>
+ string(20) "container->a.changed"
+ ["b"]=>
+ object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+
+
+Object containing object and reference to that object:
+object(stdClass)#%d (2) {
+ ["a"]=>
+ &object(stdClass)#%d (0) {
+ }
+ ["b"]=>
+ &object(stdClass)#%d (0) {
+ }
+}
+string(58) "O:8:"stdClass":2:{s:1:"a";O:8:"stdClass":0:{}s:1:"b";R:2;}"
+object(stdClass)#%d (2) {
+ ["a"]=>
+ &object(stdClass)#%d (0) {
+ }
+ ["b"]=>
+ &object(stdClass)#%d (0) {
+ }
+}
+object(stdClass)#%d (2) {
+ ["a"]=>
+ &object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+ ["b"]=>
+ &object(stdClass)#%d (1) {
+ ["a"]=>
+ string(7) "newProp"
+ }
+}
+object(stdClass)#%d (2) {
+ ["a"]=>
+ &string(20) "container->a.changed"
+ ["b"]=>
+ &string(20) "container->a.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_013.phpt b/ext/standard/tests/serialize/serialization_objects_013.phpt
new file mode 100644
index 0000000000..01b623cb0d
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_013.phpt
@@ -0,0 +1,494 @@
+--TEST--
+Object serialization / unserialization: references amongst properties
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$obj) {
+ var_dump($obj);
+ $ser = serialize($obj);
+ var_dump($ser);
+
+ $uobj = unserialize($ser);
+ var_dump($uobj);
+ $uobj->a = "obj->a.changed";
+ var_dump($uobj);
+ $uobj->b = "obj->b.changed";
+ var_dump($uobj);
+ $uobj->c = "obj->c.changed";
+ var_dump($uobj);
+}
+
+echo "\n\n--- a refs b:\n";
+$obj = new stdClass;
+$obj->a = &$obj->b;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a refs c:\n";
+$obj = new stdClass;
+$obj->a = &$obj->c;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->a;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs c:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->c;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- c refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$obj->a;
+check($obj);
+
+echo "\n\n--- c refs b:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$obj->b;
+check($obj);
+
+echo "\n\n--- a,b refs c:\n";
+$obj = new stdClass;
+$obj->a = &$obj->c;
+$obj->b = &$obj->c;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,c refs b:\n";
+$obj = new stdClass;
+$obj->a = &$obj->b;
+$obj->b = 1;
+$obj->c = &$obj->b;
+check($obj);
+
+echo "\n\n--- b,c refs a:\n";
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$obj->a;
+$obj->c = &$obj->a;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+
+--- a refs b:
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"b";i:1;s:1:"a";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a refs c:
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"c";i:1;s:1:"a";R:2;s:1:"b";i:1;}"
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->a.changed"
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->a.changed"
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->c.changed"
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+}
+
+
+--- b refs a:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- b refs c:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["c"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"c";i:1;s:1:"b";R:3;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["c"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["c"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- c refs a:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- c refs b:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";R:3;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- a,b refs c:
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"c";i:1;s:1:"a";R:2;s:1:"b";R:2;}"
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->a.changed"
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->b.changed"
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["c"]=>
+ &string(14) "obj->c.changed"
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- a,c refs b:
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"b";i:1;s:1:"a";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &int(1)
+ ["a"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["b"]=>
+ &string(14) "obj->c.changed"
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- b,c refs a:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_014.phpt b/ext/standard/tests/serialize/serialization_objects_014.phpt
new file mode 100644
index 0000000000..234f5e084c
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_014.phpt
@@ -0,0 +1,295 @@
+--TEST--
+Object serialization / unserialization: references to external values
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+function check(&$obj) {
+ var_dump($obj);
+ $ser = serialize($obj);
+ var_dump($ser);
+
+ $uobj = unserialize($ser);
+ var_dump($uobj);
+ $uobj->a = "obj->a.changed";
+ var_dump($uobj);
+ $uobj->b = "obj->b.changed";
+ var_dump($uobj);
+ $uobj->c = "obj->c.changed";
+ var_dump($uobj);
+}
+
+echo "\n\n--- a refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- b refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = &$ext;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- c refs external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = 1;
+$obj->b = 1;
+$obj->c = &$ext;
+check($obj);
+
+echo "\n\n--- a,b ref external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = &$ext;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b,c ref external:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$ext;
+$obj->b = &$ext;
+$obj->c = &$ext;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+
+--- a refs external:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- b refs external:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- c refs external:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a,b ref external:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a,b,c ref external:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";i:1;s:1:"b";R:2;s:1:"c";R:2;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &int(1)
+ ["b"]=>
+ &int(1)
+ ["c"]=>
+ &int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_objects_015.phpt b/ext/standard/tests/serialize/serialization_objects_015.phpt
new file mode 100644
index 0000000000..02e8279c4d
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_objects_015.phpt
@@ -0,0 +1,532 @@
+--TEST--
+Object serialization / unserialization: properties reference containing object
+--INI--
+error_reporting = E_ALL & ~E_STRICT
+--FILE--
+<?php
+
+function check(&$obj) {
+ var_dump($obj);
+ $ser = serialize($obj);
+ var_dump($ser);
+
+ $uobj = unserialize($ser);
+ var_dump($uobj);
+ $uobj->a = "obj->a.changed";
+ var_dump($uobj);
+ $uobj->b = "obj->b.changed";
+ var_dump($uobj);
+ $uobj->c = "obj->c.changed";
+ var_dump($uobj);
+}
+
+echo "\n\n--- a refs container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a eqs container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = 1;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b ref container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = &$obj;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b eq container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = $obj;
+$obj->c = 1;
+check($obj);
+
+echo "\n\n--- a,b,c ref container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = &$obj;
+$obj->b = &$obj;
+$obj->c = &$obj;
+check($obj);
+
+echo "\n\n--- a,b,c eq container:\n";
+$ext = 1;
+$obj = new stdClass;
+$obj->a = $obj;
+$obj->b = $obj;
+$obj->c = $obj;
+check($obj);
+
+echo "Done";
+?>
+--EXPECTF--
+--- a refs container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a eqs container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";i:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ int(1)
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a,b ref container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";R:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a,b eq container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["c"]=>
+ int(1)
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";r:1;s:1:"c";i:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ int(1)
+ }
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ int(1)
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+
+
+--- a,b,c ref container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["b"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["c"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";R:1;s:1:"b";R:1;s:1:"c";R:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["b"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["c"]=>
+ &object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->a.changed"
+ ["b"]=>
+ &string(14) "obj->a.changed"
+ ["c"]=>
+ &string(14) "obj->a.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->b.changed"
+ ["b"]=>
+ &string(14) "obj->b.changed"
+ ["c"]=>
+ &string(14) "obj->b.changed"
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ &string(14) "obj->c.changed"
+ ["b"]=>
+ &string(14) "obj->c.changed"
+ ["c"]=>
+ &string(14) "obj->c.changed"
+}
+
+
+--- a,b,c eq container:
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["c"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+}
+string(55) "O:8:"stdClass":3:{s:1:"a";r:1;s:1:"b";r:1;s:1:"c";r:1;}"
+object(stdClass)#%d (3) {
+ ["a"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["c"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ *RECURSION*
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+ ["c"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ *RECURSION*
+ ["c"]=>
+ *RECURSION*
+ }
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ *RECURSION*
+ }
+}
+object(stdClass)#%d (3) {
+ ["a"]=>
+ string(14) "obj->a.changed"
+ ["b"]=>
+ string(14) "obj->b.changed"
+ ["c"]=>
+ string(14) "obj->c.changed"
+}
+Done \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_precision_001.phpt b/ext/standard/tests/serialize/serialization_precision_001.phpt
new file mode 100644
index 0000000000..eb633beb74
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_precision_001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test serialize_precision (part 1)
+--INI--
+serialize_precision=10
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+var_dump(serialize(0.1));
+?>
+--EXPECTF--
+string(6) "d:0.1;" \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_precision_002.phpt b/ext/standard/tests/serialize/serialization_precision_002.phpt
new file mode 100644
index 0000000000..653fabea36
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_precision_002.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test serialize_precision (part 2)
+--INI--
+serialize_precision=75
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+var_dump(serialize(0.1));
+?>
+--EXPECTF--
+string(60) "d:0.1000000000000000055511151231257827021181583404541015625;" \ No newline at end of file
diff --git a/ext/standard/tests/serialize/serialization_resources_001.phpt b/ext/standard/tests/serialize/serialization_resources_001.phpt
new file mode 100644
index 0000000000..dbb7d3d3e9
--- /dev/null
+++ b/ext/standard/tests/serialize/serialization_resources_001.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test serialize() & unserialize() functions: resources
+--FILE--
+<?php
+/* Prototype : proto string serialize(mixed variable)
+ * Description: Returns a string representation of variable (which can later be unserialized)
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+/* Prototype : proto mixed unserialize(string variable_representation)
+ * Description: Takes a string representation of variable and recreates it
+ * Source code: ext/standard/var.c
+ * Alias to functions:
+ */
+
+echo "\n--- Testing Resource ---\n";
+$file_handle = fopen( __FILE__, "r" );
+$serialized_data = serialize( $file_handle );
+fclose($file_handle);
+var_dump($serialized_data);
+var_dump(unserialize($serialized_data));
+
+echo "\nDone";
+?>
+--EXPECTF--
+--- Testing Resource ---
+string(4) "i:%d;"
+int(%d)
+
+Done \ No newline at end of file