I have added the callbacks to class_entry structure and patches to
serialization mechanism to allow custom object
serialization/unserialization inside the PHP serialize mechanism.
Purpose:
--------
Define possibility for custom serialization and userialization of PHP5
objects, which would allow users to run custom code when objects are
serialized and unserialized.
Implementation:
---------------
Define 2 callbacks for zend_class_entry, as follows:
int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len,
zend_serialize_data *data TSRMLS_DC);
Serializes object data into the buffer. Should serialize only object
"internals", not class name.
zend_serialize_data is the variables hash that var.c uses to track
references. If you want to use it, consult var.c and use it the same way.
int (*unserialize)(zval **object, const unsigned char *buf,
zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
creates new zval according to the serialized data in buf,
buf_len limits data length. Returns SUCCESS if object
created correctly, FAILURE if it failed. Data include only the object
data, not class name, etc.
zend_unserialize_data is the variables hash that var_unserialize.re uses
to track references. If you want to use it, consult var.c and use it the
same way.
By default, these callbacks are NULL, meaning the standard mechanism is
used.
Format
------
New serialization is using letter 'C' to designate custom serialization
data.
Example
-------
Attached in the example patch for SimpleXML that demonstrates the concept
by using callbacks to serialize SimpleXML object's data as XML and then
restoring it to the object back. This should allow, for example, to
seamlessly put SimpleXML object to a session data.
--
Stanislav Malyshev, Zend Products Engineer
[EMAIL PROTECTED] http://www.zend.com/ +972-3-6139665 ext.115
Index: simplexml.c
===================================================================
RCS file: /repository/php-src/ext/simplexml/simplexml.c,v
retrieving revision 1.147
diff -u -b -r1.147 simplexml.c
--- simplexml.c 5 Dec 2004 12:02:35 -0000 1.147
+++ simplexml.c 22 Feb 2005 13:27:59 -0000
@@ -1681,6 +1681,71 @@
{NULL, NULL, NULL}
};
+int simplexml_serialize(zval *object, unsigned char **buffer, zend_uint
*buf_len, zend_serialize_data *data TSRMLS_DC)
+{
+ php_sxe_object *sxe;
+ xmlNodePtr node;
+ xmlOutputBufferPtr outbuf;
+ xmlChar *strval;
+ int strval_len;
+
+ sxe = php_sxe_fetch_object(object TSRMLS_CC);
+ GET_NODE(sxe, node);
+ node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
+
+ if (node) {
+ if (XML_DOCUMENT_NODE == node->parent->type) {
+ xmlDocDumpMemory((xmlDocPtr) sxe->document->ptr,
&strval, &strval_len);
+ } else {
+ /* Should we be passing encoding information instead of
NULL? */
+ outbuf = xmlAllocOutputBuffer(NULL);
+
+ if (outbuf == NULL) {
+ return FAILURE;
+ }
+
+ xmlNodeDumpOutput(outbuf, (xmlDocPtr)
sxe->document->ptr, node, 0, 1, ((xmlDocPtr) sxe->document->ptr)->encoding);
+ xmlOutputBufferFlush(outbuf);
+ strval = xmlStrndup(outbuf->buffer->content,
outbuf->buffer->use);
+ xmlOutputBufferClose(outbuf);
+ }
+
+ *buffer = estrdup(strval);
+ *buf_len = strlen(*buffer);
+ xmlFree(strval);
+ } else {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+int simplexml_unserialize(zval **object, const unsigned char *buf, zend_uint
buf_len, zend_unserialize_data *unserialize_data TSRMLS_DC)
+{
+ php_sxe_object *sxe;
+ xmlDocPtr docp;
+ zend_class_entry *ce= sxe_class_entry;
+
+#if LIBXML_VERSION >= 20600
+ docp = xmlReadMemory(buf, buf_len, NULL, NULL, 0);
+#else
+ docp = xmlParseMemory(buf, buf_len);
+#endif
+
+ if (! docp) {
+ return FAILURE;
+ }
+
+ sxe = php_sxe_object_new(ce TSRMLS_CC);
+ php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp
TSRMLS_CC);
+ php_libxml_increment_node_ptr((php_libxml_node_object *)sxe,
xmlDocGetRootElement(docp), NULL TSRMLS_CC);
+
+ MAKE_STD_ZVAL(*object);
+ Z_TYPE_PP(object) = IS_OBJECT;
+ (*object)->value.obj = php_sxe_register_object(sxe TSRMLS_CC);
+ return SUCCESS;
+}
+
/* {{{ PHP_MINIT_FUNCTION(simplexml)
*/
PHP_MINIT_FUNCTION(simplexml)
@@ -1691,6 +1756,8 @@
sxe.create_object = sxe_object_new;
sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC);
sxe_class_entry->get_iterator = php_sxe_get_iterator;
+ sxe_class_entry->serialize = simplexml_serialize;
+ sxe_class_entry->unserialize = simplexml_unserialize;
zend_class_implements(sxe_class_entry TSRMLS_CC, 1,
zend_ce_traversable);
sxe_object_handlers.get_method =
zend_get_std_object_handlers()->get_method;
sxe_object_handlers.get_constructor =
zend_get_std_object_handlers()->get_constructor;
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php