How can I return an object into PHP userspace from my extension?

Ask about general coding issues or problems here.

Moderators: egami, macek, gesf

Post Reply
User avatar
liangchaoxi
New php-forum User
New php-forum User
Posts: 1
Joined: Tue Jan 30, 2018 5:29 pm

Tue Jan 30, 2018 5:42 pm

I have a C++ object, Graph, which contains a property named cat of type Category. I'm exposing the Graph object to PHP in an extension I'm writing in C++.

As long as the Graph's methods return primitives like boolean or long, I can use the Zend RETURN_*() macros (e.g. RETURN_TRUE(); or RETURN_LONG(123);. But how can I make


Graph->getCategory();

return a Category object for the PHP code to manipulate?

I'm following the tutorial over at http://devzone.zend.com/article/4486, and here's the Graph code I have so far:




#include "php_getgraph.h"

zend_object_handlers graph_object_handlers;
struct graph_object {
zend_object std;
Graph *graph;
};

zend_class_entry *graph_ce;
#define PHP_CLASSNAME "WFGraph"

ZEND_BEGIN_ARG_INFO_EX(php_graph_one_arg, 0, 0, 1)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(php_graph_two_args, 0, 0, 2)
ZEND_END_ARG_INFO()


void graph_free_storage(void *object TSRMLS_DC)
{
graph_object *obj = (graph_object*)object;
delete obj->graph;

zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);

efree(obj);
}

zend_object_value graph_create_handler(zend_class_entry *type TSRMLS_DC)
{
zval *tmp;
zend_object_value retval;

graph_object *obj = (graph_object*)emalloc(sizeof(graph_object));
memset(obj, 0, sizeof(graph_object));
obj->std.ce = type;

ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(obj->std.properties, &type->default_properties, (copy_ctor_func_t)zval_add_ref, (void*)&tmp, sizeof(zval*));

retval.handle = zend_objects_store_put(obj, NULL, graph_free_storage, NULL TSRMLS_CC);
retval.handlers = &graph_object_handlers;

return retval;
}

PHP_METHOD(Graph, __construct)
{
char *perspectives;
int perspectives_len;
Graph *graph = NULL;
zval *object = getThis();

if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &perspectives, &perspectives_len) == FAILURE) {
RETURN_NULL();
}

graph = new Graph(perspectives);
graph_object *obj = (graph_object*)zend_object_store_get_object(object TSRMLS_CC);
obj->graph = graph;
}
PHP_METHOD(Graph, hasCategory)
{
long perspectiveId;

Graph *graph;
graph_object *obj = (graph_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
graph = obj->graph;

if (graph == NULL) {
RETURN_NULL();
}

if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &perspectiveId) == FAILURE) {
RETURN_NULL();
}

RETURN_BOOL(graph->hasCategory(perspectiveId));
}
PHP_METHOD(Graph, getCategory)
{
// what to do here?
RETURN_TRUE;
}
function_entry php_getgraph_functions[] = {
PHP_ME(Graph,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)

PHP_ME(Graph,hasCategory,php_graph_one_arg,ZEND_ACC_PUBLIC)
PHP_ME(Graph,getCategory,php_graph_one_arg,ZEND_ACC_PUBLIC)
{ NULL, NULL, NULL }
};

PHP_MINIT_FUNCTION(getgraph)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, PHP_CLASSNAME, php_getgraph_functions);
graph_ce = zend_register_internal_class(&ce TSRMLS_CC);
graph_ce->create_object = graph_create_handler;
memcpy(&graph_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
graph_object_handlers.clone_obj = NULL;
return SUCCESS;
}

zend_module_entry getgraph_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_GETGRAPH_EXTNAME,
NULL, /* Functions */
PHP_MINIT(getgraph),
NULL, /* MSHUTDOWN */
NULL, /* RINIT */
NULL, /* RSHUTDOWN */
NULL, /* MINFO */
#if ZEND_MODULE_API_NO >= 20010901
PHP_GETGRAPH_EXTVER,
#endif
STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_GETGRAPH
extern "C" {
ZEND_GET_MODULE(getgraph)
}
#endif

Post Reply