Skip to content

Commit 0655d8c

Browse files
committed
Implement "Followup improvements for ext/uri" RFC - WHATWG URL building
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
1 parent 8569b82 commit 0655d8c

60 files changed

Lines changed: 2207 additions & 24 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ext/uri/php_uri.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
+----------------------------------------------------------------------+
1313
*/
1414

15+
#include "zend_smart_str.h"
1516
#ifdef HAVE_CONFIG_H
1617
# include <config.h>
1718
#endif
@@ -34,6 +35,7 @@ zend_class_entry *php_uri_ce_rfc3986_uri_builder;
3435
zend_class_entry *php_uri_ce_rfc3986_uri;
3536
zend_class_entry *php_uri_ce_rfc3986_uri_type;
3637
zend_class_entry *php_uri_ce_rfc3986_uri_host_type;
38+
zend_class_entry *php_uri_ce_whatwg_url_builder;
3739
zend_class_entry *php_uri_ce_whatwg_url;
3840
zend_class_entry *php_uri_ce_comparison_mode;
3941
zend_class_entry *php_uri_ce_exception;
@@ -74,6 +76,15 @@ static zend_always_inline zval *php_uri_deref(zval *zv)
7476
#define Z_RFC3986_URI_PROP_QUERY_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5))
7577
#define Z_RFC3986_URI_PROP_FRAGMENT_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))
7678

79+
#define Z_WHATWG_URL_PROP_SCHEME_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0))
80+
#define Z_WHATWG_URL_PROP_USERNAME_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1))
81+
#define Z_WHATWG_URL_PROP_PASSWORD_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2))
82+
#define Z_WHATWG_URL_PROP_HOST_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3))
83+
#define Z_WHATWG_URL_PROP_PORT_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4))
84+
#define Z_WHATWG_URL_PROP_PATH_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5))
85+
#define Z_WHATWG_URL_PROP_QUERY_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))
86+
#define Z_WHATWG_URL_PROP_FRAGMENT_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 7))
87+
7788
static HashTable *uri_get_debug_properties(php_uri_object *object)
7889
{
7990
const HashTable *std_properties = zend_std_get_properties(&object->std);
@@ -1245,6 +1256,133 @@ PHP_METHOD(Uri_Rfc3986_UriBuilder, build)
12451256
uri_object->uri = uriparser_uris;
12461257
}
12471258

1259+
PHP_METHOD(Uri_WhatWg_UrlBuilder, reset)
1260+
{
1261+
zval_ptr_dtor(Z_WHATWG_URL_PROP_SCHEME_P(ZEND_THIS));
1262+
ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_SCHEME_P(ZEND_THIS));
1263+
convert_to_null(Z_WHATWG_URL_PROP_USERNAME_P(ZEND_THIS));
1264+
convert_to_null(Z_WHATWG_URL_PROP_PASSWORD_P(ZEND_THIS));
1265+
convert_to_null(Z_WHATWG_URL_PROP_HOST_P(ZEND_THIS));
1266+
convert_to_null(Z_WHATWG_URL_PROP_PORT_P(ZEND_THIS));
1267+
zval_ptr_dtor(Z_WHATWG_URL_PROP_PATH_P(ZEND_THIS));
1268+
ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_PATH_P(ZEND_THIS));
1269+
convert_to_null(Z_WHATWG_URL_PROP_QUERY_P(ZEND_THIS));
1270+
convert_to_null(Z_WHATWG_URL_PROP_FRAGMENT_P(ZEND_THIS));
1271+
1272+
RETVAL_COPY(ZEND_THIS);
1273+
}
1274+
1275+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setScheme)
1276+
{
1277+
php_uri_builder_set_component_string(
1278+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1279+
ZEND_STRL("scheme"),
1280+
php_uri_parser_whatwg_validate_scheme
1281+
);
1282+
}
1283+
1284+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setUsername)
1285+
{
1286+
php_uri_builder_set_component_string_or_null(
1287+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1288+
ZEND_STRL("username"),
1289+
php_uri_parser_whatwg_validate_none
1290+
);
1291+
}
1292+
1293+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setPassword)
1294+
{
1295+
php_uri_builder_set_component_string_or_null(
1296+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1297+
ZEND_STRL("password"),
1298+
php_uri_parser_whatwg_validate_none
1299+
);
1300+
}
1301+
1302+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setHost)
1303+
{
1304+
php_uri_builder_set_component_string_or_null(
1305+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1306+
ZEND_STRL("host"),
1307+
php_uri_parser_whatwg_validate_none
1308+
);
1309+
}
1310+
1311+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setPort)
1312+
{
1313+
php_uri_builder_set_component_long_or_null(
1314+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1315+
ZEND_STRL("port"),
1316+
php_uri_parser_whatwg_validate_port
1317+
);
1318+
}
1319+
1320+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setPath)
1321+
{
1322+
php_uri_builder_set_component_string(
1323+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1324+
ZEND_STRL("path"),
1325+
php_uri_parser_whatwg_validate_none
1326+
);
1327+
}
1328+
1329+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setQuery)
1330+
{
1331+
php_uri_builder_set_component_string_or_null(
1332+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1333+
ZEND_STRL("query"),
1334+
php_uri_parser_whatwg_validate_none
1335+
);
1336+
}
1337+
1338+
PHP_METHOD(Uri_WhatWg_UrlBuilder, setFragment)
1339+
{
1340+
php_uri_builder_set_component_string_or_null(
1341+
INTERNAL_FUNCTION_PARAM_PASSTHRU,
1342+
ZEND_STRL("fragment"),
1343+
php_uri_parser_whatwg_validate_none
1344+
);
1345+
}
1346+
1347+
PHP_METHOD(Uri_WhatWg_UrlBuilder, build)
1348+
{
1349+
zval *base_url_zv = NULL;
1350+
zval *errors = NULL;
1351+
1352+
ZEND_PARSE_PARAMETERS_START(0, 2)
1353+
Z_PARAM_OPTIONAL
1354+
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(base_url_zv, php_uri_ce_whatwg_url)
1355+
Z_PARAM_ZVAL(errors)
1356+
ZEND_PARSE_PARAMETERS_END();
1357+
1358+
const zval *scheme = Z_WHATWG_URL_PROP_SCHEME_P(ZEND_THIS);
1359+
const zval *username = Z_WHATWG_URL_PROP_USERNAME_P(ZEND_THIS);
1360+
const zval *password = Z_WHATWG_URL_PROP_PASSWORD_P(ZEND_THIS);
1361+
const zval *host = Z_WHATWG_URL_PROP_HOST_P(ZEND_THIS);
1362+
const zval *port = Z_WHATWG_URL_PROP_PORT_P(ZEND_THIS);
1363+
const zval *path = Z_WHATWG_URL_PROP_PATH_P(ZEND_THIS);
1364+
const zval *query = Z_WHATWG_URL_PROP_QUERY_P(ZEND_THIS);
1365+
const zval *fragment = Z_WHATWG_URL_PROP_FRAGMENT_P(ZEND_THIS);
1366+
1367+
lxb_url_t *base_url = NULL;
1368+
if (base_url_zv != NULL) {
1369+
base_url = Z_URI_OBJECT_P(base_url_zv)->uri;
1370+
}
1371+
1372+
lxb_url_t *lexbor_url = php_uri_parser_whatwg_build_from_zval(
1373+
base_url, scheme, username, password, host, port, path, query, fragment,
1374+
errors
1375+
);
1376+
if (lexbor_url == NULL) {
1377+
RETURN_THROWS();
1378+
}
1379+
1380+
object_init_ex(return_value, php_uri_ce_whatwg_url);
1381+
php_uri_object *uri_object = Z_URI_OBJECT_P(return_value);
1382+
uri_object->parser = &php_uri_parser_whatwg;
1383+
uri_object->uri = lexbor_url;
1384+
}
1385+
12481386
PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser)
12491387
{
12501388
php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type);
@@ -1327,6 +1465,8 @@ static PHP_MINIT_FUNCTION(uri)
13271465
php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType();
13281466
php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType();
13291467

1468+
php_uri_ce_whatwg_url_builder = register_class_Uri_WhatWg_UrlBuilder();
1469+
13301470
php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url();
13311471
php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg;
13321472
php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri;

ext/uri/php_uri.stub.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,39 @@ enum UrlHostType
210210
case Empty;
211211
}
212212

213+
final class UrlBuilder
214+
{
215+
private string $scheme = "";
216+
private ?string $username = null;
217+
private ?string $password = null;
218+
private ?string $host = null;
219+
private ?int $port = null;
220+
private string $path = "";
221+
private ?string $query = null;
222+
private ?string $fragment = null;
223+
224+
public function reset(): static {}
225+
226+
public function setScheme(string $scheme): static {}
227+
228+
public function setUsername(?string $username): static {}
229+
230+
public function setPassword(#[\SensitiveParameter] ?string $password): static {}
231+
232+
public function setHost(?string $host): static {}
233+
234+
public function setPort(?int $port): static {}
235+
236+
public function setPath(string $path): static {}
237+
238+
public function setQuery(?string $query): static {}
239+
240+
public function setFragment(?string $fragment): static {}
241+
242+
/** @param array $errors */
243+
public function build(?\Uri\WhatWg\Url $baseUrl = null, &$errors = null): \Uri\WhatWg\Url {}
244+
}
245+
213246
/** @strict-properties */
214247
final readonly class Url
215248
{

ext/uri/php_uri_arginfo.h

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

0 commit comments

Comments
 (0)