@@ -13,6 +13,8 @@ extern "C" {
1313#include " values.h"
1414#include " macros.h"
1515
16+ #define USE_MAGIC_ISSET 0
17+
1618using namespace node_php_embed ;
1719
1820/* Class Entries */
@@ -81,6 +83,36 @@ class JsHasPropertyMsg : public MessageToJs {
8183 }
8284};
8385
86+ #if USE_MAGIC_ISSET
87+
88+ PHP_METHOD (JsObject, __isset) {
89+ zval *member;
90+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, " z/" , &member) == FAILURE) {
91+ zend_throw_exception (
92+ zend_exception_get_default (TSRMLS_C),
93+ " bad property name for __isset" , 0 TSRMLS_CC);
94+ return ;
95+ }
96+ convert_to_string (member);
97+ node_php_jsobject *obj = (node_php_jsobject *)
98+ zend_object_store_get_object (this_ptr TSRMLS_CC);
99+ JsHasPropertyMsg msg (obj->channel , obj->id , member, 0 );
100+ obj->channel ->Send (&msg);
101+ msg.WaitForResponse ();
102+ // ok, result is in msg.retval_ or msg.exception_
103+ if (msg.HasException ()) {
104+ zend_throw_exception_ex (
105+ zend_exception_get_default (TSRMLS_C), 0 TSRMLS_CC,
106+ " JS exception thrown during __isset of \" %*s\" " ,
107+ Z_STRLEN_P (member), Z_STRVAL_P (member));
108+ return ;
109+ }
110+ RETURN_BOOL (msg.retval_ .AsBool ());
111+ }
112+
113+ #else
114+ // By overriding has_property we can implement property_exists correctly,
115+ // and also handle empty arrays.
84116static int node_php_jsobject_has_property (zval *object, zval *member, int has_set_exists ZEND_HASH_KEY_DC TSRMLS_DC) {
85117 /* param has_set_exists:
86118 * 0 (has) whether property exists and is not NULL - isset()
@@ -99,6 +131,7 @@ static int node_php_jsobject_has_property(zval *object, zval *member, int has_se
99131 if (msg.HasException ()) { return false ; /* sigh */ }
100132 return msg.retval_ .AsBool ();
101133}
134+ #endif /* USE_MAGIC_ISSET */
102135
103136class JsReadPropertyMsg : public MessageToJs {
104137 Value object_;
@@ -129,23 +162,30 @@ class JsReadPropertyMsg : public MessageToJs {
129162 }
130163};
131164
132- static zval *node_php_jsobject_read_property (zval *object, zval *member, int type ZEND_HASH_KEY_DC TSRMLS_DC) {
133- ZVal retval (ZEND_FILE_LINE_C);
134- if (Z_TYPE_P (member) != IS_STRING) {
135- return retval.Escape ();
165+
166+ PHP_METHOD (JsObject, __get) {
167+ zval *member;
168+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, " z/" , &member) == FAILURE) {
169+ zend_throw_exception (zend_exception_get_default (TSRMLS_C), " bad property name" , 0 TSRMLS_CC);
170+ return ;
136171 }
172+ convert_to_string (member);
137173 node_php_jsobject *obj = (node_php_jsobject *)
138- zend_object_store_get_object (object TSRMLS_CC);
139- JsReadPropertyMsg msg (obj->channel , obj->id , member, type );
174+ zend_object_store_get_object (this_ptr TSRMLS_CC);
175+ JsReadPropertyMsg msg (obj->channel , obj->id , member, 0 );
140176 obj->channel ->Send (&msg);
141177 msg.WaitForResponse ();
142178 // ok, result is in msg.retval_ or msg.exception_
143- if (msg.HasException ()) { msg.retval_ .SetNull (); /* sigh */ }
144- msg.retval_ .ToPhp (obj->channel , retval TSRMLS_CC);
145- return retval.Escape ();
179+ if (msg.HasException ()) {
180+ zend_throw_exception_ex (
181+ zend_exception_get_default (TSRMLS_C), 0 TSRMLS_CC,
182+ " JS exception thrown during __get of \" %*s\" " ,
183+ Z_STRLEN_P (member), Z_STRVAL_P (member));
184+ return ;
185+ }
186+ msg.retval_ .ToPhp (obj->channel , return_value, return_value_ptr TSRMLS_CC);
146187}
147188
148-
149189static void node_php_jsobject_free_storage (void *object, zend_object_handle handle TSRMLS_DC) {
150190 node_php_jsobject *c = (node_php_jsobject *) object;
151191
@@ -224,11 +264,22 @@ STUB_METHOD(__construct)
224264STUB_METHOD(__sleep)
225265STUB_METHOD(__wakeup)
226266
267+ ZEND_BEGIN_ARG_INFO_EX(node_php_jsobject_one_arg, 0 , 0 , 1 )
268+ ZEND_ARG_INFO(0 , member)
269+ ZEND_END_ARG_INFO()
270+ ZEND_BEGIN_ARG_INFO_EX(node_php_jsobject_one_arg_retref, 0 , 1 , 1 )
271+ ZEND_ARG_INFO(0 , member)
272+ ZEND_END_ARG_INFO()
273+
227274static const zend_function_entry node_php_jsobject_methods[] = {
228275 PHP_ME (JsObject, __construct, NULL , ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
229276 PHP_ME (JsObject, __sleep, NULL , ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
230277 PHP_ME (JsObject, __wakeup, NULL , ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
231- {NULL , NULL , NULL }
278+ #if USE_MAGIC_ISSET
279+ PHP_ME (JsObject, __isset, node_php_jsobject_one_arg, ZEND_ACC_PUBLIC)
280+ #endif
281+ PHP_ME (JsObject, __get, node_php_jsobject_one_arg_retref, ZEND_ACC_PUBLIC)
282+ ZEND_FE_END
232283};
233284
234285
@@ -245,8 +296,10 @@ PHP_MINIT_FUNCTION(node_php_jsobject_class) {
245296 node_php_jsobject_handlers.clone_obj = NULL ;
246297 node_php_jsobject_handlers.cast_object = NULL ;
247298 node_php_jsobject_handlers.get_property_ptr_ptr = NULL ;
299+ #if !USE_MAGIC_ISSET
248300 node_php_jsobject_handlers.has_property = node_php_jsobject_has_property;
249- node_php_jsobject_handlers.read_property = node_php_jsobject_read_property;
301+ #endif
302+ // node_php_jsobject_handlers.read_property = node_php_jsobject_read_property;
250303 /*
251304 node_php_jsobject_handlers.write_property = node_php_jsobject_write_property;
252305 node_php_jsobject_handlers.unset_property = node_php_jsobject_unset_property;
0 commit comments