cvs: php4 /ext/wddx wddx.c
| From: | Andrei Zmievski | Date: | Fri, 16 Jun 2000 19:50:45 +0000 |
| Subject: | cvs: php4 /ext/wddx wddx.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-317@lists.php.net to get a copy of this message | ||
andrei Fri Jun 16 12:50:45 2000 EDT
Modified files:
/php4/ext/wddx wddx.c
Log:
@- Enhanced WDDX functions to call __sleep() and __wakeup() when working on
@ objects. (Andrei)
Index: php4/ext/wddx/wddx.c
diff -u php4/ext/wddx/wddx.c:1.39 php4/ext/wddx/wddx.c:1.40
--- php4/ext/wddx/wddx.c:1.39 Fri Jun 16 11:14:51 2000
+++ php4/ext/wddx/wddx.c Fri Jun 16 12:50:45 2000
@@ -27,7 +27,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: wddx.c,v 1.39 2000/06/16 18:14:51 eschmid Exp $ */
+/* $Id: wddx.c,v 1.40 2000/06/16 19:50:45 andrei Exp $ */
#include "php.h"
#include "php_wddx.h"
@@ -380,63 +380,122 @@
}
/* }}} */
-/* {{{ void php_wddx_serialize_hash(wddx_packet *packet, zval *var) */
-static void php_wddx_serialize_hash(wddx_packet *packet, zval *var)
+static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
{
- zval **ent;
+ zval **ent, *retval, *fname, **varname;
char *key;
- int is_struct = 0, ent_type;
ulong idx;
- HashTable *target_hash;
char tmp_buf[WDDX_BUF_LEN];
- target_hash = HASH_OF(var);
-
- /* If variable is an object, always use struct and serialize its classname */
- if (var->type == IS_OBJECT) {
+ MAKE_STD_ZVAL(fname);
+ ZVAL_STRING(fname, "__sleep", 1);
+
+ /*
+ * We try to call __sleep() method on object. It's supposed to return an
+ * array of property names to be serialized.
+ */
+ if (call_user_function_ex(CG(function_table), obj, fname, &retval, 0, 0, 1) == SUCCESS) {
+ if (retval && HASH_OF(retval)) {
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
+ sprintf(tmp_buf, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
+ php_wddx_add_chunk(packet, tmp_buf);
+ php_wddx_add_chunk_static(packet, WDDX_STRING_S);
+ php_wddx_add_chunk_ex(packet, obj->value.obj.ce->name,
obj->value.obj.ce->name_length);
+ php_wddx_add_chunk_static(packet, WDDX_STRING_E);
+ php_wddx_add_chunk_static(packet, WDDX_VAR_E);
+
+ for (zend_hash_internal_pointer_reset(HASH_OF(retval));
+ zend_hash_get_current_data(HASH_OF(retval), (void **)&varname) == SUCCESS;
+ zend_hash_move_forward(HASH_OF(retval))) {
+ if (Z_TYPE_PP(varname) != IS_STRING) {
+ php_error(E_NOTICE, "__sleep should return an array only containing the names of
instance-variables to serialize.");
+ continue;
+ }
+
+ if (zend_hash_find(HASH_OF(obj), Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, (void
**)&ent) == SUCCESS) {
+ php_wddx_serialize_var(packet, *ent, Z_STRVAL_PP(varname));
+ }
+ }
+
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
+ }
+ } else {
php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
sprintf(tmp_buf, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
php_wddx_add_chunk(packet, tmp_buf);
php_wddx_add_chunk_static(packet, WDDX_STRING_S);
- php_wddx_add_chunk_ex(packet, var->value.obj.ce->name,
var->value.obj.ce->name_length);
+ php_wddx_add_chunk_ex(packet, obj->value.obj.ce->name,
obj->value.obj.ce->name_length);
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
php_wddx_add_chunk_static(packet, WDDX_VAR_E);
- is_struct = 1;
- } else {
- int ind = 0,type;
-
- for (zend_hash_internal_pointer_reset(target_hash);
- zend_hash_get_current_data(target_hash, (void**)&ent) == SUCCESS;
- zend_hash_move_forward(target_hash)) {
+ for (zend_hash_internal_pointer_reset(HASH_OF(obj));
+ zend_hash_get_current_data(HASH_OF(obj), (void**)&ent) == SUCCESS;
+ zend_hash_move_forward(HASH_OF(obj))) {
+ if (*ent == obj)
+ continue;
- type = zend_hash_get_current_key(target_hash, &key, &idx);
-
- if (type == HASH_KEY_IS_STRING) {
- is_struct = 1;
+ if (zend_hash_get_current_key(HASH_OF(obj), &key, &idx) == HASH_KEY_IS_STRING) {
+ php_wddx_serialize_var(packet, *ent, key);
efree(key);
- break;
+ } else {
+ sprintf(tmp_buf, "%ld", idx);
+ php_wddx_serialize_var(packet, *ent, tmp_buf);
}
+ }
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
+ }
- if (idx != ind) {
- is_struct = 1;
- break;
- }
+ zval_dtor(fname);
+ FREE_ZVAL(fname);
- ind++;
- }
+ if (retval) {
+ zval_dtor(retval);
+ FREE_ZVAL(retval);
+ }
+}
- if (is_struct) {
- php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
- } else {
- sprintf(tmp_buf, WDDX_ARRAY_S, zend_hash_num_elements(target_hash));
- php_wddx_add_chunk(packet, tmp_buf);
+static void php_wddx_serialize_array(wddx_packet *packet, zval *arr)
+{
+ zval **ent;
+ char *key;
+ int is_struct = 0, ent_type;
+ ulong idx;
+ HashTable *target_hash;
+ char tmp_buf[WDDX_BUF_LEN];
+ int ind = 0,type;
+
+ target_hash = HASH_OF(arr);
+
+ for (zend_hash_internal_pointer_reset(target_hash);
+ zend_hash_get_current_data(target_hash, (void**)&ent) == SUCCESS;
+ zend_hash_move_forward(target_hash)) {
+
+ type = zend_hash_get_current_key(target_hash, &key, &idx);
+
+ if (type == HASH_KEY_IS_STRING) {
+ is_struct = 1;
+ efree(key);
+ break;
}
+
+ if (idx != ind) {
+ is_struct = 1;
+ break;
+ }
+
+ ind++;
+ }
+
+ if (is_struct) {
+ php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
+ } else {
+ sprintf(tmp_buf, WDDX_ARRAY_S, zend_hash_num_elements(target_hash));
+ php_wddx_add_chunk(packet, tmp_buf);
}
for (zend_hash_internal_pointer_reset(target_hash);
zend_hash_get_current_data(target_hash, (void**)&ent) == SUCCESS;
zend_hash_move_forward(target_hash)) {
- if (*ent == var)
+ if (*ent == arr)
continue;
if (is_struct) {
@@ -459,7 +518,6 @@
php_wddx_add_chunk_static(packet, WDDX_ARRAY_E);
}
}
-/* }}} */
/* {{{ void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name) */
@@ -491,8 +549,11 @@
break;
case IS_ARRAY:
+ php_wddx_serialize_array(packet, var);
+ break;
+
case IS_OBJECT:
- php_wddx_serialize_hash(packet, var);
+ php_wddx_serialize_object(packet, var);
break;
}
@@ -653,13 +714,12 @@
if (ent1->varname) {
if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) &&
- ent1->data->type == IS_STRING &&
- ent1->data->value.str.len)
- {
+ ent1->data->type == IS_STRING && ent1->data->value.str.len) {
+ zval *fname, *retval;
+
if (zend_hash_find(EG(class_table), ent1->data->value.str.val,
ent1->data->value.str.len+1, (void **) &ce)==FAILURE) {
- php_error(E_NOTICE, "Deserializing non-existant class: %s! No methods will be
available!",
- ent1->data->value.str.val);
+ php_error(E_NOTICE, "Deserializing non-existant class: %s! No methods will be
available!", ent1->data->value.str.val);
ce = &zend_standard_class_def;
}
@@ -684,6 +744,19 @@
/* Clean up class name var entry */
zval_dtor(ent1->data);
efree(ent1->data);
+
+ /* Call __wakeup() method on the object. */
+ MAKE_STD_ZVAL(fname);
+ ZVAL_STRING(fname, "__wakeup", 1);
+
+ call_user_function_ex(NULL, obj, fname, &retval, 0, 0, 0);
+
+ zval_dtor(fname);
+ FREE_ZVAL(fname);
+ if (retval) {
+ zval_dtor(retval);
+ FREE_ZVAL(retval);
+ }
}
else
zend_hash_update(target_hash,