11<?php namespace Illuminate \Support ;
22
3- use Closure ;
4- use Serializable ;
5- use SplFileObject ;
6- use ReflectionFunction ;
7-
83/**
9- * Do not use this class unless you really know what you're doing!
10- *
11- * @author Taylor Otwell <@taylorotwell>
12- * @author Jeremy Lindblom <@jeremeamia>
4+ * Extending for backwards compatibility.
135 */
14- class SerializableClosure implements Serializable {
15-
16- /**
17- * The Closure instance.
18- *
19- * @var \Closure
20- */
21- protected $ closure ;
22-
23- /**
24- * The ReflectionFunction instance of the Closure.
25- *
26- * @var \ReflectionFunction
27- */
28- protected $ reflection ;
29-
30- /**
31- * The code contained by the Closure.
32- *
33- * @var string
34- */
35- protected $ code ;
36-
37- /**
38- * Create a new serializable Closure instance.
39- *
40- * @param \Closure $closure
41- * @return void
42- */
43- public function __construct (Closure $ closure )
44- {
45- $ this ->closure = $ closure ;
46-
47- $ this ->reflection = new ReflectionFunction ($ closure );
48- }
49-
50- /**
51- * Get the code for the Closure.
52- *
53- * @return string
54- */
55- public function getCode ()
56- {
57- return $ this ->code ?: $ this ->code = $ this ->getCodeFromFile ();
58- }
59-
60- /**
61- * Extract the code from the Closure's file.
62- *
63- * @return string
64- */
65- protected function getCodeFromFile ()
66- {
67- $ file = $ this ->getFile ();
68-
69- $ code = '' ;
70-
71- // Next, we will just loop through the lines of the file until we get to the end
72- // of the Closure. Then, we will return the complete contents of this Closure
73- // so it can be serialized with these variables and stored for later usage.
74- while ($ file ->key () < $ this ->reflection ->getEndLine ())
75- {
76- $ code .= $ file ->current (); $ file ->next ();
77- }
78-
79- $ begin = strpos ($ code , 'function( ' );
80-
81- return substr ($ code , $ begin , strrpos ($ code , '} ' ) - $ begin + 1 );
82- }
83-
84- /**
85- * Get an SplObjectFile object at the starting line of the Closure.
86- *
87- * @return \SplFileObject
88- */
89- protected function getFile ()
90- {
91- $ file = new SplFileObject ($ this ->reflection ->getFileName ());
92-
93- $ file ->seek ($ this ->reflection ->getStartLine () - 1 );
94-
95- return $ file ;
96- }
97-
98- /**
99- * Get the variables used by the Closure.
100- *
101- * @return array
102- */
103- public function getVariables ()
104- {
105- if ( ! $ this ->getUseIndex ()) return array ();
106-
107- $ staticVariables = $ this ->reflection ->getStaticVariables ();
108-
109- // When looping through the variables, we will only take the variables that are
110- // specified in the use clause, and will not take any other static variables
111- // that may be used by the Closures, allowing this to re-create its state.
112- $ usedVariables = array ();
113-
114- foreach ($ this ->getUseClauseVariables () as $ variable )
115- {
116- $ variable = trim ($ variable , ' $& ' );
117-
118- $ usedVariables [$ variable ] = $ staticVariables [$ variable ];
119- }
120-
121- return $ usedVariables ;
122- }
123-
124- /**
125- * Get the variables from the "use" clause.
126- *
127- * @return array
128- */
129- protected function getUseClauseVariables ()
130- {
131- $ begin = strpos ($ code = $ this ->getCode (), '( ' , $ this ->getUseIndex ()) + 1 ;
132-
133- return explode (', ' , substr ($ code , $ begin , strpos ($ code , ') ' , $ begin ) - $ begin ));
134- }
135-
136- /**
137- * Get the index location of the "use" clause.
138- *
139- * @return int
140- */
141- protected function getUseIndex ()
142- {
143- return stripos (strtok ($ this ->getCode (), PHP_EOL ), ' use ' );
144- }
145-
146- /**
147- * Serialize the Closure instance.
148- *
149- * @return string
150- */
151- public function serialize ()
152- {
153- return serialize (array (
154- 'code ' => $ this ->getCode (), 'variables ' => $ this ->getVariables ()
155- ));
156- }
157-
158- /**
159- * Unserialize the Closure instance.
160- *
161- * @param string $serialized
162- * @return void
163- */
164- public function unserialize ($ serialized )
165- {
166- $ payload = unserialize ($ serialized );
167-
168- // We will extract the variables into the current scope so that as the Closure
169- // is built it will inherit the scope it had before it was serialized which
170- // will emulate the Closures existing in that scope instead of right now.
171- extract ($ payload ['variables ' ]);
172-
173- eval ('$this->closure = ' .$ payload ['code ' ].'; ' );
174-
175- $ this ->reflection = new ReflectionFunction ($ this ->closure );
176- }
177-
178- /**
179- * Get the unserialized Closure instance.
180- *
181- * @return \Closure
182- */
183- public function getClosure ()
184- {
185- return $ this ->closure ;
186- }
187-
188- /**
189- * Invoke the contained Closure.
190- *
191- * @return mixed
192- */
193- public function __invoke ()
194- {
195- return call_user_func_array ($ this ->closure , func_get_args ());
196- }
197-
198- }
6+ class SerializableClosure extends \Jeremeamia \SuperClosure \SerializableClosure {}
0 commit comments