Skip to content

Commit dc0f489

Browse files
committed
Migrate SOAP URL resource to object
Related to https://wiki.php.net/rfc/resource_to_object_conversion and php/php-tasks#6
1 parent 9c49cf5 commit dc0f489

File tree

6 files changed

+97
-26
lines changed

6 files changed

+97
-26
lines changed

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ PHP 8.4 UPGRADE NOTES
135135
. Calling simplexml_import_dom() with a non-XML object now throws a TypeError
136136
instead of a ValueError.
137137

138+
- SOAP:
139+
. SoapClient::$httpurl is now a Soap\Url object rather than a resource.
140+
Value checks using is_resource() should be replaced with checks for `null`.
141+
138142
- SPL:
139143
. Out of bounds accesses in SplFixedArray now throw an exception of type
140144
OutOfBoundsException instead of RuntimeException. As OutOfBoundsException

ext/soap/php_http.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ int make_http_soap_request(zval *this_ptr,
484484
if (stream != NULL) {
485485
php_url *orig;
486486
tmp = Z_CLIENT_HTTPURL_P(this_ptr);
487-
if (Z_TYPE_P(tmp) == IS_RESOURCE &&
488-
(orig = (php_url *) zend_fetch_resource_ex(tmp, "httpurl", le_url)) != NULL &&
487+
if (Z_TYPE_P(tmp) == IS_OBJECT && instanceof_function(Z_OBJCE_P(tmp), soap_url_class_entry) &&
488+
(orig = Z_SOAP_URL_P(tmp)->url) != NULL &&
489489
((use_proxy && !use_ssl) ||
490490
(((use_ssl && orig->scheme != NULL && zend_string_equals_literal(orig->scheme, "https")) ||
491491
(!use_ssl && orig->scheme == NULL) ||
@@ -536,9 +536,15 @@ int make_http_soap_request(zval *this_ptr,
536536

537537
if (stream) {
538538
zval *cookies, *login, *password;
539-
zend_resource *ret = zend_register_resource(phpurl, le_url);
540-
ZVAL_RES(Z_CLIENT_HTTPURL_P(this_ptr), ret);
541-
GC_ADDREF(ret);
539+
540+
zval *url_zval = Z_CLIENT_HTTPURL_P(this_ptr);
541+
if (Z_TYPE_P(url_zval) == IS_OBJECT) {
542+
zval_ptr_dtor(url_zval);
543+
}
544+
545+
object_init_ex(url_zval, soap_url_class_entry);
546+
soap_url_object *url_obj = Z_SOAP_URL_P(url_zval);
547+
url_obj->url = phpurl;
542548

543549
if (context &&
544550
(tmp = php_stream_context_get_option(context, "http", "protocol_version")) != NULL &&

ext/soap/php_soap.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
# define stricmp strcasecmp
4141
#endif
4242

43-
extern int le_url;
44-
4543
typedef struct _encodeType encodeType, *encodeTypePtr;
4644
typedef struct _encode encode, *encodePtr;
4745

@@ -194,6 +192,7 @@ ZEND_TSRMLS_CACHE_EXTERN()
194192

195193
extern zend_class_entry* soap_class_entry;
196194
extern zend_class_entry* soap_var_class_entry;
195+
extern zend_class_entry* soap_url_class_entry;
197196

198197
void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail);
199198

@@ -253,4 +252,15 @@ static zend_always_inline zval *php_soap_deref(zval *zv) {
253252
#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 34))
254253
#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 35))
255254

255+
typedef struct {
256+
php_url *url;
257+
zend_object std;
258+
} soap_url_object;
259+
260+
static inline soap_url_object *soap_url_object_fetch(zend_object *obj)
261+
{
262+
return (soap_url_object *) ((char *) obj - XtOffsetOf(soap_url_object, std));
263+
}
264+
265+
#define Z_SOAP_URL_P(zv) soap_url_object_fetch(Z_OBJ_P(zv))
256266
#endif

ext/soap/soap.c

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131

3232
static int le_sdl = 0;
33-
int le_url = 0;
3433
static int le_typemap = 0;
3534

3635
typedef struct _soapHeader {
@@ -65,7 +64,6 @@ static xmlNodePtr serialize_parameter(sdlParamPtr param,zval *param_val,int inde
6564
static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent);
6665

6766
static void delete_service(void *service);
68-
static void delete_url(void *handle);
6967
static void delete_hashtable(void *hashtable);
7068

7169
static void soap_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
@@ -178,8 +176,10 @@ static zend_class_entry* soap_fault_class_entry;
178176
static zend_class_entry* soap_header_class_entry;
179177
static zend_class_entry* soap_param_class_entry;
180178
zend_class_entry* soap_var_class_entry;
179+
zend_class_entry *soap_url_class_entry;
181180

182181
static zend_object_handlers soap_server_object_handlers;
182+
static zend_object_handlers soap_url_object_handlers;
183183

184184
typedef struct {
185185
soapServicePtr service;
@@ -206,6 +206,34 @@ static void soap_server_object_free(zend_object *obj) {
206206
zend_object_std_dtor(obj);
207207
}
208208

209+
static zend_object *soap_url_object_create(zend_class_entry *ce)
210+
{
211+
soap_url_object *url_obj = zend_object_alloc(sizeof(soap_url_object), ce);
212+
213+
zend_object_std_init(&url_obj->std, ce);
214+
object_properties_init(&url_obj->std, ce);
215+
216+
return &url_obj->std;
217+
}
218+
219+
static void soap_url_object_free(zend_object *obj)
220+
{
221+
soap_url_object *url_obj = soap_url_object_fetch(obj);
222+
223+
if (url_obj->url) {
224+
php_url_free(url_obj->url);
225+
url_obj->url = NULL;
226+
}
227+
228+
zend_object_std_dtor(&url_obj->std);
229+
}
230+
231+
static zend_function *soap_url_object_get_constructor(zend_object *object)
232+
{
233+
zend_throw_error(NULL, "Cannot directly construct Soap\\Url");
234+
235+
return NULL;
236+
}
209237
ZEND_DECLARE_MODULE_GLOBALS(soap)
210238

211239
static void (*old_error_handler)(int, zend_string *, const uint32_t, zend_string *);
@@ -395,11 +423,6 @@ static void delete_sdl_res(zend_resource *res)
395423
delete_sdl(res->ptr);
396424
}
397425

398-
static void delete_url_res(zend_resource *res)
399-
{
400-
delete_url(res->ptr);
401-
}
402-
403426
static void delete_hashtable_res(zend_resource *res)
404427
{
405428
delete_hashtable(res->ptr);
@@ -436,9 +459,19 @@ PHP_MINIT_FUNCTION(soap)
436459
soap_header_class_entry = register_class_SoapHeader();
437460

438461
le_sdl = zend_register_list_destructors_ex(delete_sdl_res, NULL, "SOAP SDL", module_number);
439-
le_url = zend_register_list_destructors_ex(delete_url_res, NULL, "SOAP URL", module_number);
440462
le_typemap = zend_register_list_destructors_ex(delete_hashtable_res, NULL, "SOAP table", module_number);
441463

464+
soap_url_class_entry = register_class_Soap_Url();
465+
soap_url_class_entry->create_object = soap_url_object_create;
466+
soap_url_class_entry->default_object_handlers = &soap_url_object_handlers;
467+
468+
memcpy(&soap_url_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
469+
soap_url_object_handlers.offset = XtOffsetOf(soap_url_object, std);
470+
soap_url_object_handlers.free_obj = soap_url_object_free;
471+
soap_url_object_handlers.get_constructor = soap_url_object_get_constructor;
472+
soap_url_object_handlers.clone_obj = NULL;
473+
soap_url_object_handlers.compare = zend_objects_not_comparable;
474+
442475
register_soap_symbols(module_number);
443476

444477
old_error_handler = zend_error_cb;
@@ -4355,12 +4388,6 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */
43554388
}
43564389
/* }}} */
43574390

4358-
static void delete_url(void *handle) /* {{{ */
4359-
{
4360-
php_url_free((php_url*)handle);
4361-
}
4362-
/* }}} */
4363-
43644391
static void delete_service(void *data) /* {{{ */
43654392
{
43664393
soapServicePtr service = (soapServicePtr)data;

ext/soap/soap.stub.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22

33
/** @generate-class-entries */
44

5-
namespace {
5+
namespace Soap {
6+
/**
7+
* @strict-properties
8+
* @not-serializable
9+
*/
10+
class Url
11+
{
12+
}
13+
}
614

15+
namespace {
716
/**
817
* @var int
918
* @cvalue SOAP_1_1
@@ -525,8 +534,7 @@ class SoapClient
525534
private $typemap = null;
526535
/** @var resource|null */
527536
private $httpsocket = null;
528-
/** @var resource|null */
529-
private $httpurl = null;
537+
private ?Soap\Url $httpurl = null;
530538

531539
private ?string $_login = null;
532540
private ?string $_password = null;

ext/soap/soap_arginfo.h

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)