Skip to content

Commit a077dd4

Browse files
committed
Convert resource to object in XML-RPC extension
1 parent 707cb18 commit a077dd4

File tree

4 files changed

+96
-78
lines changed

4 files changed

+96
-78
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,12 @@ PHP 8.0 UPGRADE NOTES
409409
instead the XmlParser instance is automatically destroyed if it is no longer
410410
referenced.
411411

412+
- XML-RPC:
413+
. xmlrpc_server_create() will now return an XmlRpcServer object rather than a resource.
414+
The xmlrpc_server_destroy() function no longer has an effect,
415+
instead the XmlRpcServer instance is automatically destroyed if it is no longer
416+
referenced.
417+
412418
- XMLWriter:
413419
. The XMLWriter functions now accept and return, respectively, XMLWriter
414420
objects instead of resources.

ext/xmlrpc/xmlrpc-epi-php.c

Lines changed: 77 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
#include "xmlrpc.h"
7171
#include "xmlrpc_arginfo.h"
7272

73-
static int le_xmlrpc_server;
73+
#include "Zend/zend_interfaces.h"
7474

7575
zend_module_entry xmlrpc_module_entry = {
7676
STANDARD_MODULE_HEADER,
@@ -98,6 +98,7 @@ typedef struct _xmlrpc_server_data {
9898
zval method_map;
9999
zval introspection_map;
100100
XMLRPC_SERVER server_ptr;
101+
zend_object std;
101102
} xmlrpc_server_data;
102103

103104

@@ -172,36 +173,74 @@ XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str);
172173
int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type);
173174

174175
/*********************
175-
* startup / shutdown *
176+
* XmlRpcServer object *
176177
*********************/
177178

178-
static void destroy_server_data(xmlrpc_server_data *server)
179+
zend_class_entry *xmlrpc_server_ce;
180+
static zend_object_handlers xmlrpc_server_object_handlers;
181+
static const zend_function_entry xmlrpc_server_object_methods[] = {
182+
PHP_FE_END
183+
};
184+
185+
static inline xmlrpc_server_data *xmlrpc_server_from_obj(zend_object *obj) {
186+
return (xmlrpc_server_data *)((char *)(obj) - XtOffsetOf(xmlrpc_server_data, std));
187+
}
188+
189+
#define Z_XMLRPC_SERVER_P(zv) xmlrpc_server_from_obj(Z_OBJ_P(zv))
190+
191+
static zend_object *xmlrpc_server_create_object(zend_class_entry *class_type) {
192+
xmlrpc_server_data *intern = zend_object_alloc(sizeof(xmlrpc_server_data), class_type);
193+
194+
zend_object_std_init(&intern->std, class_type);
195+
object_properties_init(&intern->std, class_type);
196+
intern->std.handlers = &xmlrpc_server_object_handlers;
197+
198+
return &intern->std;
199+
}
200+
201+
static zend_function *xmlrpc_server_get_constructor(zend_object *object) {
202+
zend_throw_error(NULL, "Cannot directly construct XmlRpcServer, use xmlrpc_server_create() instead");
203+
return NULL;
204+
}
205+
206+
static void xmlrpc_server_free_obj(zend_object *object)
179207
{
180-
if (server) {
181-
XMLRPC_ServerDestroy(server->server_ptr);
208+
xmlrpc_server_data *server = xmlrpc_server_from_obj(object);
182209

183-
zval_ptr_dtor(&server->method_map);
184-
zval_ptr_dtor(&server->introspection_map);
210+
XMLRPC_ServerDestroy(server->server_ptr);
185211

186-
efree(server);
187-
}
212+
zval_ptr_dtor(&server->method_map);
213+
zval_ptr_dtor(&server->introspection_map);
214+
zend_object_std_dtor(&server->std);
188215
}
189216

190-
/* called when server is being destructed. either when xmlrpc_server_destroy
191-
* is called, or when request ends. */
192-
static void xmlrpc_server_destructor(zend_resource *rsrc)
217+
static HashTable *xmlrpc_server_get_gc(zend_object *object, zval **table, int *n)
193218
{
194-
if (rsrc && rsrc->ptr) {
195-
GC_ADDREF(rsrc);
196-
destroy_server_data((xmlrpc_server_data*) rsrc->ptr);
197-
GC_DELREF(rsrc);
198-
}
219+
xmlrpc_server_data *xmlrpc_server = xmlrpc_server_from_obj(object);
220+
221+
*table = &xmlrpc_server->method_map;
222+
*n = 2;
223+
224+
return zend_std_get_properties(object);
199225
}
200226

201227
/* module init */
202228
PHP_MINIT_FUNCTION(xmlrpc)
203229
{
204-
le_xmlrpc_server = zend_register_list_destructors_ex(xmlrpc_server_destructor, NULL, "xmlrpc server", module_number);
230+
zend_class_entry ce;
231+
INIT_CLASS_ENTRY(ce, "XmlRpcServer", xmlrpc_server_object_methods);
232+
xmlrpc_server_ce = zend_register_internal_class(&ce);
233+
xmlrpc_server_ce->ce_flags |= ZEND_ACC_FINAL;
234+
xmlrpc_server_ce->create_object = xmlrpc_server_create_object;
235+
xmlrpc_server_ce->serialize = zend_class_serialize_deny;
236+
xmlrpc_server_ce->unserialize = zend_class_unserialize_deny;
237+
238+
memcpy(&xmlrpc_server_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
239+
xmlrpc_server_object_handlers.offset = XtOffsetOf(xmlrpc_server_data, std);
240+
xmlrpc_server_object_handlers.free_obj = xmlrpc_server_free_obj;
241+
xmlrpc_server_object_handlers.get_gc = xmlrpc_server_get_gc;
242+
xmlrpc_server_object_handlers.get_constructor = xmlrpc_server_get_constructor;
243+
xmlrpc_server_object_handlers.clone_obj = NULL;
205244

206245
return SUCCESS;
207246
}
@@ -735,7 +774,7 @@ PHP_FUNCTION(xmlrpc_decode)
735774
* server related methods *
736775
*************************/
737776

738-
/* {{{ proto resource xmlrpc_server_create(void)
777+
/* {{{ proto XmlRpcServer xmlrpc_server_create(void)
739778
Creates an xmlrpc server */
740779
PHP_FUNCTION(xmlrpc_server_create)
741780
{
@@ -744,42 +783,31 @@ PHP_FUNCTION(xmlrpc_server_create)
744783
}
745784

746785
if (USED_RET()) {
747-
xmlrpc_server_data *server = emalloc(sizeof(xmlrpc_server_data));
786+
xmlrpc_server_data *server;
787+
788+
object_init_ex(return_value, xmlrpc_server_ce);
789+
server = Z_XMLRPC_SERVER_P(return_value);
748790

749-
/* allocate server data. free'd in destroy_server_data() */
750791
array_init(&server->method_map);
751792
array_init(&server->introspection_map);
752793
server->server_ptr = XMLRPC_ServerCreate();
753794

754795
XMLRPC_ServerRegisterIntrospectionCallback(server->server_ptr, php_xmlrpc_introspection_callback);
755-
756-
/* store for later use */
757-
RETURN_RES(zend_register_resource(server, le_xmlrpc_server));
758796
}
759797
}
760798
/* }}} */
761799

762-
/* {{{ proto int xmlrpc_server_destroy(resource server)
800+
/* {{{ proto bool xmlrpc_server_destroy(XmlRpcServer server)
763801
Destroys server resources */
764802
PHP_FUNCTION(xmlrpc_server_destroy)
765803
{
766804
zval *arg1;
767-
int bSuccess = FAILURE;
768-
xmlrpc_server_data *server;
769-
770-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
771-
RETURN_THROWS();
772-
}
773805

774-
if ((server = (xmlrpc_server_data *)zend_fetch_resource(Z_RES_P(arg1), "xmlrpc server", le_xmlrpc_server)) == NULL) {
806+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg1, xmlrpc_server_ce) == FAILURE) {
775807
RETURN_THROWS();
776808
}
777809

778-
bSuccess = zend_list_close(Z_RES_P(arg1));
779-
/* called by hashtable destructor
780-
* destroy_server_data(server);
781-
*/
782-
RETURN_BOOL(bSuccess == SUCCESS);
810+
RETURN_TRUE;
783811
}
784812
/* }}} */
785813

@@ -881,7 +909,7 @@ static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data)
881909
}
882910
/* }}} */
883911

884-
/* {{{ proto bool xmlrpc_server_register_method(resource server, string method_name, string function)
912+
/* {{{ proto bool xmlrpc_server_register_method(XmlRpcServer server, string method_name, string function)
885913
Register a PHP function to handle method matching method_name */
886914
PHP_FUNCTION(xmlrpc_server_register_method)
887915
{
@@ -890,13 +918,11 @@ PHP_FUNCTION(xmlrpc_server_register_method)
890918
zval *handle, *method_name;
891919
xmlrpc_server_data* server;
892920

893-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz", &handle, &method_key, &method_key_len, &method_name) == FAILURE) {
921+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osz", &handle, xmlrpc_server_ce, &method_key, &method_key_len, &method_name) == FAILURE) {
894922
RETURN_THROWS();
895923
}
896924

897-
if ((server = (xmlrpc_server_data *)zend_fetch_resource(Z_RES_P(handle), "xmlrpc server", le_xmlrpc_server)) == NULL) {
898-
RETURN_THROWS();
899-
}
925+
server = Z_XMLRPC_SERVER_P(handle);
900926

901927
/* register with C engine. every method just calls our standard callback,
902928
* and it then dispatches to php as necessary
@@ -913,20 +939,18 @@ PHP_FUNCTION(xmlrpc_server_register_method)
913939
}
914940
/* }}} */
915941

916-
/* {{{ proto bool xmlrpc_server_register_introspection_callback(resource server, string function)
942+
/* {{{ proto bool xmlrpc_server_register_introspection_callback(XmlRpcServer server, string function)
917943
Register a PHP function to generate documentation */
918944
PHP_FUNCTION(xmlrpc_server_register_introspection_callback)
919945
{
920946
zval *method_name, *handle;
921947
xmlrpc_server_data* server;
922948

923-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &handle, &method_name) == FAILURE) {
949+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &handle, xmlrpc_server_ce, &method_name) == FAILURE) {
924950
RETURN_THROWS();
925951
}
926952

927-
if ((server = (xmlrpc_server_data *)zend_fetch_resource(Z_RES_P(handle), "xmlrpc server", le_xmlrpc_server)) == NULL) {
928-
RETURN_THROWS();
929-
}
953+
server = Z_XMLRPC_SERVER_P(handle);
930954

931955
Z_TRY_ADDREF_P(method_name);
932956
/* register our php method */
@@ -938,7 +962,7 @@ PHP_FUNCTION(xmlrpc_server_register_introspection_callback)
938962

939963
/* this function is itchin for a re-write */
940964

941-
/* {{{ proto mixed xmlrpc_server_call_method(resource server, string xml, mixed user_data [, array output_options])
965+
/* {{{ proto mixed xmlrpc_server_call_method(XmlRpcServer server, string xml, mixed user_data [, array output_options])
942966
Parses XML requests and call methods */
943967
PHP_FUNCTION(xmlrpc_server_call_method)
944968
{
@@ -952,7 +976,7 @@ PHP_FUNCTION(xmlrpc_server_call_method)
952976
php_output_options out;
953977
int argc = ZEND_NUM_ARGS();
954978

955-
if (zend_parse_parameters(argc, "rsz|a", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) {
979+
if (zend_parse_parameters(argc, "Osz|a", &handle, xmlrpc_server_ce, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) {
956980
RETURN_THROWS();
957981
}
958982
/* user output options */
@@ -962,9 +986,7 @@ PHP_FUNCTION(xmlrpc_server_call_method)
962986
set_output_options(&out, output_opts);
963987
}
964988

965-
if ((server = (xmlrpc_server_data *)zend_fetch_resource(Z_RES_P(handle), "xmlrpc server", le_xmlrpc_server)) == NULL) {
966-
RETURN_THROWS();
967-
}
989+
server = Z_XMLRPC_SERVER_P(handle);
968990

969991
/* HACK: use output encoding for now */
970992
input_opts.xml_elem_opts.encoding = utf8_get_encoding_id_from_string(out.xmlrpc_out.xml_elem_opts.encoding);
@@ -1046,21 +1068,19 @@ PHP_FUNCTION(xmlrpc_server_call_method)
10461068
}
10471069
/* }}} */
10481070

1049-
/* {{{ proto int xmlrpc_server_add_introspection_data(resource server, array desc)
1071+
/* {{{ proto int xmlrpc_server_add_introspection_data(XmlRpcServer server, array desc)
10501072
Adds introspection documentation */
10511073
PHP_FUNCTION(xmlrpc_server_add_introspection_data)
10521074
{
10531075
zval *handle, *desc;
10541076
xmlrpc_server_data* server;
10551077
XMLRPC_VALUE xDesc;
10561078

1057-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &handle, &desc) == FAILURE) {
1079+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa", &handle, xmlrpc_server_ce, &desc) == FAILURE) {
10581080
RETURN_THROWS();
10591081
}
10601082

1061-
if ((server = (xmlrpc_server_data *)zend_fetch_resource(Z_RES_P(handle), "xmlrpc server", le_xmlrpc_server)) == NULL) {
1062-
RETURN_THROWS();
1063-
}
1083+
server = Z_XMLRPC_SERVER_P(handle);
10641084

10651085
xDesc = PHP_to_XMLRPC(desc);
10661086
if (xDesc) {

ext/xmlrpc/xmlrpc.stub.php

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,18 @@ function xmlrpc_set_type(&$value, string $type): bool {}
1919

2020
function xmlrpc_is_fault(array $arg): bool {}
2121

22-
/** @return resource */
23-
function xmlrpc_server_create() {}
22+
function xmlrpc_server_create(): XmlRpcServer {}
2423

25-
/** @param resource $server */
26-
function xmlrpc_server_destroy($server): bool {}
24+
function xmlrpc_server_destroy(XmlRpcServer $server): bool {}
2725

28-
/** @param resource $server */
29-
function xmlrpc_server_register_method($server, string $method_name, $function): bool {}
26+
function xmlrpc_server_register_method(XmlRpcServer $server, string $method_name, $function): bool {}
3027

31-
/**
32-
* @param resource $server
33-
* @return mixed
34-
*/
35-
function xmlrpc_server_call_method($server, string $xml, $user_data, array $output_options = UNKNOWN) {}
28+
/** @return mixed */
29+
function xmlrpc_server_call_method(XmlRpcServer $server, string $xml, $user_data, array $output_options = UNKNOWN) {}
3630

3731
/** @return mixed */
3832
function xmlrpc_parse_method_descriptions(string $xml) {}
3933

40-
/** @param resource $server */
41-
function xmlrpc_server_add_introspection_data($server, array $desc): int {}
34+
function xmlrpc_server_add_introspection_data(XmlRpcServer $server, array $desc): int {}
4235

43-
/** @param resource $server */
44-
function xmlrpc_server_register_introspection_callback($server, $function): bool {}
36+
function xmlrpc_server_register_introspection_callback(XmlRpcServer $server, $function): bool {}

ext/xmlrpc/xmlrpc_arginfo.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,21 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_is_fault, 0, 1, _IS_BOOL,
3434
ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0)
3535
ZEND_END_ARG_INFO()
3636

37-
ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlrpc_server_create, 0, 0, 0)
37+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xmlrpc_server_create, 0, 0, XmlRpcServer, 0)
3838
ZEND_END_ARG_INFO()
3939

4040
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_destroy, 0, 1, _IS_BOOL, 0)
41-
ZEND_ARG_INFO(0, server)
41+
ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0)
4242
ZEND_END_ARG_INFO()
4343

4444
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_register_method, 0, 3, _IS_BOOL, 0)
45-
ZEND_ARG_INFO(0, server)
45+
ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0)
4646
ZEND_ARG_TYPE_INFO(0, method_name, IS_STRING, 0)
4747
ZEND_ARG_INFO(0, function)
4848
ZEND_END_ARG_INFO()
4949

5050
ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlrpc_server_call_method, 0, 0, 3)
51-
ZEND_ARG_INFO(0, server)
51+
ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0)
5252
ZEND_ARG_TYPE_INFO(0, xml, IS_STRING, 0)
5353
ZEND_ARG_INFO(0, user_data)
5454
ZEND_ARG_TYPE_INFO(0, output_options, IS_ARRAY, 0)
@@ -59,12 +59,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlrpc_parse_method_descriptions, 0, 0, 1)
5959
ZEND_END_ARG_INFO()
6060

6161
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_add_introspection_data, 0, 2, IS_LONG, 0)
62-
ZEND_ARG_INFO(0, server)
62+
ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0)
6363
ZEND_ARG_TYPE_INFO(0, desc, IS_ARRAY, 0)
6464
ZEND_END_ARG_INFO()
6565

6666
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_register_introspection_callback, 0, 2, _IS_BOOL, 0)
67-
ZEND_ARG_INFO(0, server)
67+
ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0)
6868
ZEND_ARG_INFO(0, function)
6969
ZEND_END_ARG_INFO()
7070

0 commit comments

Comments
 (0)