gpt4 book ai didi

php - 如何从我的扩展中将对象返回到 PHP 用户空间?

转载 作者:行者123 更新时间:2023-11-30 03:10:53 27 4
gpt4 key购买 nike

我有一个 C++ 对象 Graph,它包含一个名为 catCategory 类型的属性。我在用 C++ 编写的扩展中将 Graph 对象公开给 PHP。

只要 Graph 的方法返回原语,如 boolean 或 long,我就可以使用 Zend RETURN_*() 宏(例如 RETURN_TRUE() ;RETURN_LONG(123);。但是我怎样才能使


图->getCategory();

返回一个 Category 对象供 PHP 代码操作?

我正在学习 http://devzone.zend.com/article/4486 上的教程,这是我目前拥有的图表代码:

#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

最佳答案

在你的内部函数中,你只能返回 zvals,而不是任意的 C++ 对象。在您的情况下,您必须将 Category 对象封装在资源或对象中(就像您对 Graph 对象所做的那样)。无论哪种方式,您都不能自动使用 C++ 对象的方法和属性。然后,您必须提供函数或方法(同样,就像您为 Graph 对象所做的那样),然后调用底层本地方法并将其结果转换为 zvals。

编辑:好的,我假设您已经将 Category 类声明为一个 PHP 类,它的类条目表在 ce_category 中并且您有这个类型:

struct category_object {
zend_object std;
Category *categ;
};

然后:

PHP_METHOD(Graph, getCategory)
{
graph_object *obj = (graph_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
struct category_object *co;

//You ought to check whether obj is NULL and maybe throw an exception or call zend_error...
if (object_init_ex(return_value, ce_category) != SUCCESS) {
//error handling
}

co = (struct category_object *) zend_object_store_get_object(return_value TSRMLS_CC);
assert (co != NULL); //should not happen; object was just created
co->categ = retrieve_category_from_graph(obj->graph);

/* IMPORTANT NOTE: if the Category object is held by the Graph object
* (that is, it is freed when the Graph object is freed), you should either:
* - Copy the Category object, so that it is independent.
* - Increment the refcount of the PHP Graph object with
* zend_objects_store_add_ref(_by_handle). In that case, you should also store the
* handle of the PHP Graph object so that you can decrease the refcount when the
* PHP Category object is destroyed. Alternatively, you can store an IS_OBJECT
* zval and indirectly manipulate the object refcount through construction/destruction
* of the zval */
}

关于php - 如何从我的扩展中将对象返回到 PHP 用户空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2822272/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com