# Writeing OO exteions for PHP 4.3

- Thread: https://externals.io/message/12562
- Original archive: https://news-web.php.net/php.internals/12562
- Started by Jan Gerritsen on 2004-09-03T14:54:56+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

---

## #12562 — Jan Gerritsen — 2004-09-03T14:54:56+00:00

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

Hello,

I want to write an OO extension in C++ for my PHP 4.3.8 under linux.

I have already written some extensions in C for my own purposes, which
introduce new functions to PHP.
Studying the sources of ext/standard/dir.c, ext/ming/ming.c and the
tutorial from J Smith (http://bugs.tutorbuddy.com/phpcpp/phpcpp/) I got
already this far:

I have managed to build and link the CPP sources as a shared object
which can be loaded and called from PHP.
I have introduced the new class to PHP using the following code in the
PHP_MINIT_FUNCTION of my extension:

static zend_class_entry *url_class_entry_ptr;
static int le_url;

function_entry url_class_functions[] = {
	PHP_FALIAS(url, url_init, NULL)
	PHP_FALIAS(set_string, url_set_string, NULL)
	{NULL, NULL, NULL}
};

static ZEND_RSRC_DTOR_FUNC(destroy_url)
{
     if (rsrc->ptr) {
         delete (Url_class*) rsrc->ptr;
         rsrc->ptr = NULL;
     }
}
PHP_MINIT_FUNCTION(url)
{
	zend_class_entry url_class_entry;
	INIT_CLASS_ENTRY(url_class_entry, "url", url_class_functions);
	url_class_entry_ptr = zend_register_internal_class(&url_class_entry
TSRMLS_CC);

	le_url = zend_register_list_destructors_ex(destroy_url, NULL, "url",
module_number);

	return SUCCESS;
}

This class can be created, and the functions (methods) can be called
from PHP.
Example:
$url = new `URL()`;
$url->set_string("12345");

Now my problem is, how can I save the pointer of my C++ class, created
in the url_init function, and restore it in the other functions/methods:
PHP_FUNCTION(url_init)
{
	Url_class * url = new Url_class;
	
	/ * code to save the address of url */
}

PHP_FUNCTION(url_set_string)
{
	Url_class *url = NULL;

	/* code to fetch url */
	
	if( url != `NULL` ) {
		url->set_string(“test”);
		RETURN_TRUE;
	}
	RETURN_FALSE;
}

I could not work out how to do this, by studying the code of the OO
extensions I mentioned.
Can someone give me a hint, ore some example code, how to do such things?

thanks
Jan Gerritsen

---

## #12563 — John Coggeshall — 2004-09-03T16:40:37+00:00

URL: https://externals.io/message/12562#12563 · In reply to: #12562

If I understand you correctly you can put this pointer inside of a
resource container and return the resource container to user space as
the return value from url_init(). Then, from url_set_string() you accept
the resource as a parameter and extract the pointer to your CPP instance
of whatever class.

John


> Hello,
> 
> I want to write an OO extension in C++ for my PHP 4.3.8 under linux.
> 
> I have already written some extensions in C for my own purposes, which
> introduce new functions to PHP.
> Studying the sources of ext/standard/dir.c, ext/ming/ming.c and the
> tutorial from J Smith (http://bugs.tutorbuddy.com/phpcpp/phpcpp/) I got
> already this far:
> 
> I have managed to build and link the CPP sources as a shared object
> which can be loaded and called from PHP.
> I have introduced the new class to PHP using the following code in the
> PHP_MINIT_FUNCTION of my extension:
> 
> static zend_class_entry *url_class_entry_ptr;
> static int le_url;
> 
> function_entry url_class_functions[] = {
> 	PHP_FALIAS(url, url_init, NULL)
> 	PHP_FALIAS(set_string, url_set_string, NULL)
> 	{NULL, NULL, NULL}
> };
> 
> static ZEND_RSRC_DTOR_FUNC(destroy_url)
> {
>      if (rsrc->ptr) {
>          delete (Url_class*) rsrc->ptr;
>          rsrc->ptr = NULL;
>      }
> }
> PHP_MINIT_FUNCTION(url)
> {
> 	zend_class_entry url_class_entry;
> 	INIT_CLASS_ENTRY(url_class_entry, "url", url_class_functions);
> 	url_class_entry_ptr = zend_register_internal_class(&url_class_entry
> TSRMLS_CC);
> 
> 	le_url = zend_register_list_destructors_ex(destroy_url, NULL, "url",
> module_number);
> 
> 	return SUCCESS;
> }
> 
> This class can be created, and the functions (methods) can be called
> from PHP.
> Example:
> $url = new `URL()`;
> $url->set_string("12345");
> 
> Now my problem is, how can I save the pointer of my C++ class, created
> in the url_init function, and restore it in the other functions/methods:
> PHP_FUNCTION(url_init)
> {
> 	Url_class * url = new Url_class;
> 	
> 	/ * code to save the address of url */
> }
> 
> PHP_FUNCTION(url_set_string)
> {
> 	Url_class *url = NULL;
> 
> 	/* code to fetch url */
> 	
> 	if( url != `NULL` ) {
> 		url->set_string(âtestâ);
> 		RETURN_TRUE;
> 	}
> 	RETURN_FALSE;
> }
> 
> I could not work out how to do this, by studying the code of the OO
> extensions I mentioned.
> Can someone give me a hint, ore some example code, how to do such things?
> 
> thanks
> Jan Gerritsen

---

## #12567 — Jan Gerritsen — 2004-09-03T18:33:51+00:00

URL: https://externals.io/message/12562#12567 · In reply to: #12563

Hi,

> If I understand you correctly you can put this pointer inside of a
> resource container and return the resource container to user space as
> the return value from url_init(). Then, from url_set_string() you accept
> the resource as a parameter and extract the pointer to your CPP instance
> of whatever class.

Tanks for your response, but your solution do not work for me, because I 
don’t get the resource_id as parameter for calls to the object. 
($php_url_object->set_string(“asdf”); )
I now save the C++ Object pointer in a resource and save this resource 
as an attribute of the PHP object.

PHP_FUNCTION(url_init)
{
	Url_class * url = new Url_class;
	zval * this_p = getThis();
	MAKE_STD_ZVAL(return_value);
	int res_id = ZEND_REGISTER_RESOURCE(NULL, url, le_url);
	add_property_resource(getThis(), "url_class_ressource", res_id);
}

It’s a little bit tricky to extract this resource and the inherit 
pointer again, like I do in my set_string function:
PHP_FUNCTION(url_set_string)
{
	zval ** ressource;
	if( zend_hash_find(getThis()->value.obj.properties,
		"url_class_ressource", sizeof("url_class_ressource"),
		(void**) &ressource) == FAILURE )
	{
		php_error_docref(NULL TSRMLS_CC, E_WARNING,
			"Could not find url_class_ressource");
		RETURN_FALSE;
	}

	if( ressource == `NULL` || (*ressource) == `NULL` 
		||(*ressource)->type != IS_RESOURCE )
	{
		php_error_docref(NULL TSRMLS_CC, E_WARNING,
			"Ressource not found");
		RETURN_FALSE;
	}

	Url_class * url;
	url = (Url_class *) zend_fetch_resource(ressource TSRMLS_CC, -1,
		"url", NULL, 1, le_url);
	ZEND_VERIFY_RESOURCE(url);

	if( url == `NULL` ) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING,
			"Ressource is invalid???");
		RETURN_FALSE;
	}

	if(url->setString("test")) {
		RETURN_TRUE;
	}

	RETURN_FALSE;
}

But I don’t get memory leeks, because php makes sure my resource is 
destructed if it is not referenced anymore:
static ZEND_RSRC_DTOR_FUNC(destroy_url)
{
	Url_class * url = (Url_class *) rsrc->ptr;;
	delete url;
}

I am not to happy with this solution, because the user can access the 
"url_class_ressource" attribute of the PHP url Object, but this will 
work for now.
Or can someone give me better solution? I am happy for everything which 
may help me,…

Greets
Jan

---

## #12569 — George Schlossnagle — 2004-09-03T21:03:04+00:00

URL: https://externals.io/message/12562#12569 · In reply to: #12567

> Hi,
>
> > […]
>
> Tanks for your response, but your solution do not work for me, because 
> I don’t get the resource_id as parameter for calls to the object. 
> ($php_url_object->set_string(“asdf”); )
> I now save the C++ Object pointer in a resource and save this resource 
> as an attribute of the PHP object.

This is a typical strategy for php4 oo stuff.

George
