# Cloning of objects passed as parameters

- Thread: https://externals.io/message/43293
- Original archive: https://news-web.php.net/php.internals/43293
- Started by Frankie Dintino on 2009-03-10T16:19:32+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #43293 — Frankie Dintino — 2009-03-10T16:19:32+00:00

URL: https://externals.io/message/43293#43293

I'm writing a PHP class with a method that has to be passed a 
DOMDocument object, and it needs to retain that object throughout the 
life of its instantiation. However, the (dom_object *) returned from 
zend_parse_method_parameters is just a pointer to the passed object, 
and so it disappears when the original document is unset or goes out of 
scope. How would one go about cloning the DOMDocument to save in the 
class's struct?

example:
ZEND_METHOD(xydelta, setStartDocument) {
	zval *id, *doc = NULL;
	xydelta_object *intern;

	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
"Oo", &id, xydelta_ce, &doc) == FAILURE) {
		RETURN_FALSE;
	}

	intern = (xydelta_object *)zend_object_store_get_object(id TSRMLS_CC);
	if (intern != NULL) {	
		// Error checking removed for brevity...
		// ...

		// This pointer cannot be accessed once the object that was used as 
the first parameter goes out of scope
		intern->libxml_start_doc = (php_libxml_node_object *) 
zend_object_store_get_object(doc TSRMLS_CC);
	}
}

---

## #43298 — Marcus Boerger — 2009-03-10T20:03:19+00:00

URL: https://externals.io/message/43293#43298 · In reply to: #43293

Hello Frankie,

Tuesday, March 10, 2009, 5:19:32 PM, you wrote:

> I'm writing a PHP class with a method that has to be passed a 
> DOMDocument object, and it needs to retain that object throughout the 
> life of its instantiation. However, the (dom_object *) returned from 
> zend_parse_method_parameters is just a pointer to the passed object, 
> and so it disappears when the original document is unset or goes out of 
> scope. How would one go about cloning the DOMDocument to save in the 
> class's struct?

> example:
> ZEND_METHOD(xydelta, setStartDocument) {
>         zval *id, *doc = NULL;
>         xydelta_object *intern;

>         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
> "Oo", &id, xydelta_ce, &doc) == FAILURE) {
>                 RETURN_FALSE;
>         }

>         intern = (xydelta_object *)zend_object_store_get_object(id TSRMLS_CC);
>         if (intern != NULL) {   
>                 // Error checking removed for brevity...
>                 // ...

>                 // This pointer cannot be accessed once the object that was used as
> the first parameter goes out of scope
>                 intern->libxml_start_doc = (php_libxml_node_object *) 
> zend_object_store_get_object(doc TSRMLS_CC);
>         }
> }



DOMDocuments are reference counted, hence zou can simplz increase their
refcount when storing the connection and delete the ref when dropping the
connection, probably in your destructor.

Best regards,
 Marcus

---

## #43330 — Frankie Dintino — 2009-03-12T04:21:49+00:00

URL: https://externals.io/message/43293#43330 · In reply to: #43298

Thanks Marcus,

Actually, persistence wasn't the only issue. I had to make sure that 
the DOMDocument wasn't later modified, as that could lead to weird 
behavior. Basically, what i needed was a way to pass an object by copy 
rather than by reference, as it was in ZE1. I figured out a solution, 
so I'm posting it here in case somebody stumbles on this post with the 
same question I had.

ZEND_METHOD(xydelta, setStartDocument) {
    zval *id, *doc = NULL;
    xydelta_object *intern;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
      getThis(),, "Oo", &id, xydelta_ce, &doc) == FAILURE) {
        RETURN_FALSE;
    }

    intern = (xydelta_object *)zend_object_store_get_object(id TSRMLS_CC);
    if (intern == NULL) {
        RETURN_FALSE;
    }
    // Error checking removed for brevity...
    // ...

    // Clone zval* doc

    zend_object_handlers *handlers = Z_OBJ_HT(doc);

    zval *doc_clone;
    MAKE_STD_ZVAL(doc_clone);
    Z_TYPE_P(doc_clone) = IS_OBJECT;
   Z_OBJVAL(doc_clone) = handlers->clone_obj(doc);

    // Get cloned object
    intern->libxml_start_doc = (php_libxml_node_object *)
        zend_object_store_get_object(doc_clone TSRMLS_CC);
    }
}



On 2009-03-10 16:03:19 -0400, helly@php.net (Marcus Boerger) said:

> Hello Frankie,
> 
> DOMDocuments are reference counted, hence zou can simplz increase their
> refcount when storing the connection and delete the ref when dropping the
> connection, probably in your destructor.
> 
> Best regards,
>  Marcus
> 
> Tuesday, March 10, 2009, 5:19:32 PM, you wrote:
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]

---

## #43341 — Frankie Dintino — 2009-03-13T20:05:43+00:00

URL: https://externals.io/message/43293#43341 · In reply to: #43330

Sorry to spam the list with a reply to my own thread again, but there 
were some errors in the example I posted, which would defeat the whole 
idea of it being useful for somebody with the same question. Corrected 
example:

ZEND_METHOD(xydelta, setStartDocument) {
    zval *id, *doc = NULL;
    xydelta_object *intern;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
      getThis(), "Oo", &id, xydelta_ce, &doc) == FAILURE) {
        RETURN_FALSE;
    }

    intern = (xydelta_object *)zend_object_store_get_object(id TSRMLS_CC);
    // Error checking removed for brevity...
    // ...

    // Clone zval* doc

    zend_object_handlers *handlers = doc->value.obj.handlers;

    zval *doc_clone;
    MAKE_STD_ZVAL(doc_clone);
    Z_TYPE_P(doc_clone) = IS_OBJECT;
    doc_clone->value.obj = handlers->clone_obj(doc);

    // Get cloned object
    intern->libxml_start_doc = (php_libxml_node_object *)
        zend_object_store_get_object(doc_clone TSRMLS_CC);
}

- Frankie Dintino

On 2009-03-12 00:21:49 -0400, fdintino@nflc.org (Frankie Dintino) said:

> 
> ...
> 
> On 2009-03-10 16:03:19 -0400, helly@php.net (Marcus Boerger) said:
> 
> > […]
