Skip to content

Commit 44c329b

Browse files
committed
Add a test of PHP magic functions.
1 parent 52d8946 commit 44c329b

File tree

2 files changed

+333
-0
lines changed

2 files changed

+333
-0
lines changed

samples/test_call.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function MyOwnFunc() {}
88
function __Get($name) {
99
echo "Called __get(): ";
1010
var_dump($name);
11+
return "xyz";
1112
}
1213
function __Set($name, $args) {
1314
echo "Called __set(): ";

tests/magic_func.phpt

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
--TEST--
2+
Test V8::executeString() : Object with magic functions
3+
--SKIPIF--
4+
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
class Foo {
9+
var $bar = 'foobar';
10+
var $nullprop = null;
11+
12+
function Foo() {
13+
echo "called constructor: ";
14+
var_dump(func_get_args());
15+
}
16+
17+
function MyOwnFunc() {
18+
echo "called MyOwnFunc\n";
19+
}
20+
21+
function __Get($name) {
22+
echo "Called __get(): ";
23+
var_dump($name);
24+
return null;
25+
}
26+
function __Set($name, $args) {
27+
echo "Called __set(): ";
28+
var_dump($name, $args);
29+
}
30+
function __Isset($name) {
31+
echo "Called __isset(): ";
32+
var_dump($name);
33+
return true;
34+
}
35+
function __unSet($name) {
36+
echo "Called __unset(): ";
37+
var_dump($name);
38+
}
39+
function __call($name, $args) {
40+
echo "Called __call(): ";
41+
var_dump($name, $args);
42+
return "call";
43+
}
44+
function __Invoke($name, $arg1, $arg2) {
45+
echo "Called __invoke(): ";
46+
var_dump(func_get_args());
47+
return 'foobar';
48+
}
49+
function __toString() {
50+
echo "Called __tostring: ";
51+
return $this->bar;
52+
}
53+
}
54+
55+
class Bar {
56+
function foo($arg1, $arg2, $arg3) {
57+
echo "Called foo(): ";
58+
var_dump(func_get_args());
59+
return "test";
60+
}
61+
}
62+
63+
64+
$blaa = new V8Js();
65+
$blaa->obj = $obj = new Foo;
66+
67+
try {
68+
echo "__invoke() [PHP]\n";
69+
var_dump($obj('arg1','arg2','arg3'));
70+
echo "__invoke() [JS]\n";
71+
$blaa->executeString("var_dump(PHP.obj('arg1','arg2','arg3'));", "invoke_test1 #1.js");
72+
echo "------------\n";
73+
74+
echo " __invoke() with new [PHP]\n";
75+
$myobj = new $obj('arg1','arg2','arg3'); $myobj->myownfunc();
76+
echo " __invoke() with new [JS]\n";
77+
$blaa->executeString("myobj = new PHP.obj('arg1','arg2','arg3'); myobj.myownfunc();", "invoke_test2 #2.js");
78+
echo "------------\n";
79+
80+
echo " __tostring() [PHP]\n";
81+
echo $obj; echo "\n";
82+
echo " __tostring() [JS]\n";
83+
$blaa->executeString('print(PHP.obj + "\n");', "tostring_test #3.js");
84+
echo "------------\n";
85+
86+
echo " __isset() not called with existing property [PHP]\n";
87+
if (isset($obj->bar)) { echo "bar exists\n"; }
88+
echo " __isset() not called with existing property [JS]\n";
89+
$blaa->executeString('if ("bar" in PHP.obj) print("bar exists\n");', "isset_test1 #4.js");
90+
echo "------------\n";
91+
92+
echo " __isset() with non-existing property [PHP]\n";
93+
if (!isset($obj->foobar)) { echo "foobar does not exist\n"; } else { echo "We called __isset and it said yes!\n"; }
94+
echo " __isset() with non-existing property [JS]\n";
95+
$blaa->executeString('if (!("foobar" in PHP.obj)) print("foobar does not exist\n"); else print("We called __isset and it said yes!\n");', "isset_test2 #5.js");
96+
echo "------------\n";
97+
98+
echo " in works like isset [PHP]\n";
99+
echo "nullprop is ", (isset($obj->nullprop) ? "" : "not "), "set\n";
100+
echo " in works like isset [JS]\n";
101+
$blaa->executeString('print("nullprop is ", ("nullprop" in PHP.obj) ? "" : "not ", "set\n");', "isset_test3 #6.js");
102+
echo "------------\n";
103+
104+
echo " __get() not called with existing property [PHP]\n";
105+
var_dump($obj->bar);
106+
echo " __get() not called with existing property [JS]\n";
107+
$blaa->executeString('var_dump(PHP.obj.bar);', "get_test1 #7.js");
108+
echo "------------\n";
109+
110+
echo " __get() with non-existing property [PHP]\n";
111+
var_dump($obj->fooish);
112+
echo " __get() with non-existing property [JS]\n";
113+
$blaa->executeString('var_dump(PHP.obj.fooish);', "get_test2 #8.js");
114+
echo "------------\n";
115+
116+
echo " __unset() with non-existing property [PHP]\n";
117+
unset($obj->foobar);
118+
echo " __unset() with non-existing property [JS]\n";
119+
$blaa->executeString('delete PHP.obj.foobar;', "unset_test1 #9.js");
120+
echo "------------\n";
121+
122+
echo " __unset() with existing property [PHP]\n";
123+
$obj2 = new Foo; unset($obj2->bar);
124+
echo " __unset() with existing property [JS]\n";
125+
$blaa->obj2 = new Foo;
126+
$blaa->executeString('delete PHP.obj2.bar;', "unset_test2 #10.js");
127+
echo " fetching the unset property [PHP]\n";
128+
var_dump($obj2->bar);
129+
echo " fetching the unset property [JS]\n";
130+
$blaa->executeString('var_dump(PHP.obj2.bar);', "unset_test3 #11.js");
131+
echo "------------\n";
132+
133+
echo " __call() [PHP]\n";
134+
var_dump($obj->fooish(1,2,3));
135+
echo " __call() [JS]\n";
136+
# note that 'PHP.obj.fooish(1,2,3)' won't work in JS, we need to use the
137+
# '__call' pseudo-method.
138+
$blaa->executeString('var_dump(PHP.obj.__call("fooish", [1,2,3]));', "call_test1 #12.js");
139+
echo "------------\n";
140+
141+
# the __call pseudo-method should work in JS even if the PHP class doesn't
142+
# define an explicit __call magic function. This makes it always safe to
143+
# use __call() if you want to be sure that any __call() handlers are invoked
144+
# (bypassing __get handlers, as is it done in PHP)
145+
$blaa->obj3 = $obj3 = new Bar;
146+
echo " __call() w/o handler [PHP]\n";
147+
var_dump($obj3->foo(1,2,3));
148+
echo " __call() w/o handler [JS]\n";
149+
$blaa->executeString('var_dump(PHP.obj3.__call("foo", [1,2,3]));', "call_test2 #13.js");
150+
echo "------------\n";
151+
152+
# The Bar object should inherit toString() and hasOwnProperty() methods
153+
# from Object
154+
echo " __toString in Bar [PHP]\n";
155+
var_dump(method_exists( $obj3, '__toString' ));
156+
echo " toString in Bar [PHP]\n";
157+
var_dump(method_exists( $obj3, 'toString' ));
158+
echo " hasOwnProperty in Bar [PHP]\n";
159+
var_dump(method_exists( $obj3, 'hasOwnProperty' ));
160+
echo " __toString in Bar [JS]\n";
161+
$blaa->executeString('var_dump("__toString" in PHP.obj3 && typeof PHP.obj3.__toString == "function");', "inherit_test1 #14.js");
162+
# use '$toString' if you actually wanted to check for a PHP property
163+
# named 'toString' in Bar (instead of the inherited JavaScript property)
164+
echo " toString in Bar [JS]\n";
165+
$blaa->executeString('var_dump("toString" in PHP.obj3 && typeof PHP.obj3.toString == "function");', "inherit_test1 #15.js");
166+
# use '$hasOwnProperty' if you actually wanted to check for a PHP property
167+
# named 'hasOwnProperty' in Bar (instead of the inherited JavaScript property)
168+
echo " hasOwnProperty in Bar [JS]\n";
169+
$blaa->executeString('var_dump("hasOwnProperty" in PHP.obj3 && typeof PHP.obj3.hasOwnProperty == "function");', "inherit_test1 #16.js");
170+
echo "------------\n";
171+
172+
} catch (V8JsScriptException $e) {
173+
echo $e->getMessage(), "\n";
174+
}
175+
?>
176+
===EOF===
177+
--EXPECT--
178+
called constructor: array(0) {
179+
}
180+
__invoke() [PHP]
181+
Called __invoke(): array(3) {
182+
[0]=>
183+
string(4) "arg1"
184+
[1]=>
185+
string(4) "arg2"
186+
[2]=>
187+
string(4) "arg3"
188+
}
189+
string(6) "foobar"
190+
__invoke() [JS]
191+
Called __invoke(): array(3) {
192+
[0]=>
193+
string(4) "arg1"
194+
[1]=>
195+
string(4) "arg2"
196+
[2]=>
197+
string(4) "arg3"
198+
}
199+
string(6) "foobar"
200+
------------
201+
__invoke() with new [PHP]
202+
called constructor: array(3) {
203+
[0]=>
204+
string(4) "arg1"
205+
[1]=>
206+
string(4) "arg2"
207+
[2]=>
208+
string(4) "arg3"
209+
}
210+
called MyOwnFunc
211+
__invoke() with new [JS]
212+
called constructor: array(3) {
213+
[0]=>
214+
string(4) "arg1"
215+
[1]=>
216+
string(4) "arg2"
217+
[2]=>
218+
string(4) "arg3"
219+
}
220+
called MyOwnFunc
221+
------------
222+
__tostring() [PHP]
223+
Called __tostring: foobar
224+
__tostring() [JS]
225+
Called __get(): string(7) "valueOf"
226+
Called __tostring: foobar
227+
------------
228+
__isset() not called with existing property [PHP]
229+
bar exists
230+
__isset() not called with existing property [JS]
231+
bar exists
232+
------------
233+
__isset() with non-existing property [PHP]
234+
Called __isset(): string(6) "foobar"
235+
We called __isset and it said yes!
236+
__isset() with non-existing property [JS]
237+
Called __isset(): string(6) "foobar"
238+
We called __isset and it said yes!
239+
------------
240+
in works like isset [PHP]
241+
nullprop is not set
242+
in works like isset [JS]
243+
nullprop is not set
244+
------------
245+
__get() not called with existing property [PHP]
246+
string(6) "foobar"
247+
__get() not called with existing property [JS]
248+
string(6) "foobar"
249+
------------
250+
__get() with non-existing property [PHP]
251+
Called __get(): string(6) "fooish"
252+
NULL
253+
__get() with non-existing property [JS]
254+
Called __get(): string(6) "fooish"
255+
NULL
256+
------------
257+
__unset() with non-existing property [PHP]
258+
Called __unset(): string(6) "foobar"
259+
__unset() with non-existing property [JS]
260+
Called __unset(): string(6) "foobar"
261+
------------
262+
__unset() with existing property [PHP]
263+
called constructor: array(0) {
264+
}
265+
__unset() with existing property [JS]
266+
called constructor: array(0) {
267+
}
268+
fetching the unset property [PHP]
269+
Called __get(): string(3) "bar"
270+
NULL
271+
fetching the unset property [JS]
272+
Called __get(): string(3) "bar"
273+
NULL
274+
------------
275+
__call() [PHP]
276+
Called __call(): string(6) "fooish"
277+
array(3) {
278+
[0]=>
279+
int(1)
280+
[1]=>
281+
int(2)
282+
[2]=>
283+
int(3)
284+
}
285+
string(4) "call"
286+
__call() [JS]
287+
Called __call(): string(6) "fooish"
288+
array(3) {
289+
[0]=>
290+
int(1)
291+
[1]=>
292+
int(2)
293+
[2]=>
294+
int(3)
295+
}
296+
string(4) "call"
297+
------------
298+
__call() w/o handler [PHP]
299+
Called foo(): array(3) {
300+
[0]=>
301+
int(1)
302+
[1]=>
303+
int(2)
304+
[2]=>
305+
int(3)
306+
}
307+
string(4) "test"
308+
__call() w/o handler [JS]
309+
Called foo(): array(3) {
310+
[0]=>
311+
int(1)
312+
[1]=>
313+
int(2)
314+
[2]=>
315+
int(3)
316+
}
317+
string(4) "test"
318+
------------
319+
__toString in Bar [PHP]
320+
bool(false)
321+
toString in Bar [PHP]
322+
bool(false)
323+
hasOwnProperty in Bar [PHP]
324+
bool(false)
325+
__toString in Bar [JS]
326+
bool(false)
327+
toString in Bar [JS]
328+
bool(true)
329+
hasOwnProperty in Bar [JS]
330+
bool(true)
331+
------------
332+
===EOF===

0 commit comments

Comments
 (0)