1--TEST--
2custom save handler, multiple session_start()s, complex data structure test.
3--EXTENSIONS--
4session
5--INI--
6session.use_cookies=0
7session.use_strict_mode=0
8session.cache_limiter=
9session.name=PHPSESSID
10session.serialize_handler=php
11--FILE--
12<?php
13error_reporting(E_ALL);
14ob_start();
15
16class handler implements SessionHandlerInterface {
17    public $data = 'baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}}';
18    function open($save_path, $session_name): bool
19    {
20        print "OPEN: $session_name\n";
21        return true;
22    }
23    function close(): bool
24    {
25        print "CLOSE\n";
26        return true;
27    }
28    function read($key): string|false
29    {
30        print "READ: $key\n";
31        return $GLOBALS["hnd"]->data;
32    }
33
34    function write($key, $val): bool
35    {
36        print "WRITE: $key, $val\n";
37        $GLOBALS["hnd"]->data = $val;
38        return true;
39    }
40
41    function destroy($key): bool
42    {
43        print "DESTROY: $key\n";
44        return true;
45    }
46
47    function gc($max_lifetime): int { return 1; }
48}
49
50$hnd = new handler;
51
52class foo {
53    public $bar = "ok";
54    public $yes;
55    function method() { $this->yes++; }
56}
57
58session_set_save_handler($hnd);
59
60session_id("test005");
61session_start();
62session_decode($hnd->data);
63
64$_SESSION["baz"]->method();
65$_SESSION["arr"][3]->method();
66
67var_dump($_SESSION["baz"]);
68var_dump($_SESSION["arr"]);
69
70session_write_close();
71
72session_set_save_handler($hnd);
73session_start();
74$_SESSION["baz"]->method();
75$_SESSION["arr"][3]->method();
76
77
78$_SESSION["c"] = 123;
79var_dump($_SESSION["baz"]);
80var_dump($_SESSION["arr"]);
81var_dump($_SESSION["c"]);
82
83session_write_close();
84
85session_set_save_handler($hnd);
86session_start();
87var_dump($_SESSION["baz"]);
88var_dump($_SESSION["arr"]);
89var_dump($_SESSION["c"]);
90
91session_destroy();
92?>
93--EXPECT--
94OPEN: PHPSESSID
95READ: test005
96object(foo)#4 (2) {
97  ["bar"]=>
98  string(2) "ok"
99  ["yes"]=>
100  int(2)
101}
102array(1) {
103  [3]=>
104  object(foo)#2 (2) {
105    ["bar"]=>
106    string(2) "ok"
107    ["yes"]=>
108    int(2)
109  }
110}
111WRITE: test005, baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:2;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:2;}}
112CLOSE
113OPEN: PHPSESSID
114READ: test005
115object(foo)#2 (2) {
116  ["bar"]=>
117  string(2) "ok"
118  ["yes"]=>
119  int(3)
120}
121array(1) {
122  [3]=>
123  object(foo)#4 (2) {
124    ["bar"]=>
125    string(2) "ok"
126    ["yes"]=>
127    int(3)
128  }
129}
130int(123)
131WRITE: test005, baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:3;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:3;}}c|i:123;
132CLOSE
133OPEN: PHPSESSID
134READ: test005
135object(foo)#4 (2) {
136  ["bar"]=>
137  string(2) "ok"
138  ["yes"]=>
139  int(3)
140}
141array(1) {
142  [3]=>
143  object(foo)#2 (2) {
144    ["bar"]=>
145    string(2) "ok"
146    ["yes"]=>
147    int(3)
148  }
149}
150int(123)
151DESTROY: test005
152CLOSE
153