Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ PHP 8.6 UPGRADE NOTES
RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection
. Added Uri\Rfc3986\UriBuilder.
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
. Added Uri\WhatWg\UrlBuilder.
RFC: https://wiki.php.net/rfc/uri_followup#uri_building

========================================
3. Changes in SAPI modules
Expand Down
147 changes: 147 additions & 0 deletions ext/uri/php_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ zend_class_entry *php_uri_ce_rfc3986_uri_builder;
zend_class_entry *php_uri_ce_rfc3986_uri;
zend_class_entry *php_uri_ce_rfc3986_uri_type;
zend_class_entry *php_uri_ce_rfc3986_uri_host_type;
zend_class_entry *php_uri_ce_whatwg_url_builder;
zend_class_entry *php_uri_ce_whatwg_url;
zend_class_entry *php_uri_ce_comparison_mode;
zend_class_entry *php_uri_ce_exception;
Expand Down Expand Up @@ -75,6 +76,17 @@ static zend_always_inline zval *php_uri_deref(zval *zv)
#define Z_RFC3986_URI_PROP_QUERY_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5))
#define Z_RFC3986_URI_PROP_FRAGMENT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))

#define Z_WHATWG_URL_PROP_SCHEME_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 0)
#define Z_WHATWG_URL_PROP_SCHEME_DEREF_P(zv) php_uri_deref(Z_WHATWG_URL_PROP_SCHEME_P(zv))
#define Z_WHATWG_URL_PROP_USERNAME_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1))
#define Z_WHATWG_URL_PROP_PASSWORD_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2))
#define Z_WHATWG_URL_PROP_HOST_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3))
#define Z_WHATWG_URL_PROP_PORT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4))
#define Z_WHATWG_URL_PROP_PATH_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 5)
#define Z_WHATWG_URL_PROP_PATH_DEREF_P(zv) php_uri_deref(Z_WHATWG_URL_PROP_PATH_P(zv))
#define Z_WHATWG_URL_PROP_QUERY_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6))
#define Z_WHATWG_URL_PROP_FRAGMENT_DEREF_P(zv) php_uri_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 7))

static HashTable *uri_get_debug_properties(php_uri_object *object)
{
const HashTable *std_properties = zend_std_get_properties(&object->std);
Expand Down Expand Up @@ -1249,6 +1261,139 @@ PHP_METHOD(Uri_Rfc3986_UriBuilder, build)
uri_object->uri = uriparser_uris;
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, reset)
Comment thread
kocsismate marked this conversation as resolved.
{
ZEND_PARSE_PARAMETERS_NONE();

zend_object *object = Z_OBJ_P(ZEND_THIS);
zval *property = object->properties_table;
const zval *end = property + object->ce->default_properties_count;

while (property != end) {
zend_object_dtor_property(object, property);
ZVAL_NULL(property);
property++;
}

ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_SCHEME_P(ZEND_THIS));
ZVAL_EMPTY_STRING(Z_WHATWG_URL_PROP_PATH_P(ZEND_THIS));

RETVAL_COPY(ZEND_THIS);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setScheme)
{
php_uri_builder_set_component_string(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("scheme"),
php_uri_parser_whatwg_validate_scheme
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setUsername)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("username"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPassword)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("password"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setHost)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("host"),
php_uri_parser_whatwg_validate_host
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPort)
{
php_uri_builder_set_component_long_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("port"),
php_uri_parser_whatwg_validate_port
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setPath)
{
php_uri_builder_set_component_string(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("path"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setQuery)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("query"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, setFragment)
{
php_uri_builder_set_component_string_or_null(
INTERNAL_FUNCTION_PARAM_PASSTHRU,
ZEND_STRL("fragment"),
php_uri_parser_whatwg_validate_none
);
}

PHP_METHOD(Uri_WhatWg_UrlBuilder, build)
{
zval *base_url_zv = NULL;
zval *errors = NULL;

ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(base_url_zv, php_uri_ce_whatwg_url)
Comment thread
kocsismate marked this conversation as resolved.
Z_PARAM_ZVAL(errors)
ZEND_PARSE_PARAMETERS_END();

const zval *scheme = Z_WHATWG_URL_PROP_SCHEME_DEREF_P(ZEND_THIS);
const zval *username = Z_WHATWG_URL_PROP_USERNAME_DEREF_P(ZEND_THIS);
const zval *password = Z_WHATWG_URL_PROP_PASSWORD_DEREF_P(ZEND_THIS);
const zval *host = Z_WHATWG_URL_PROP_HOST_DEREF_P(ZEND_THIS);
const zval *port = Z_WHATWG_URL_PROP_PORT_DEREF_P(ZEND_THIS);
const zval *path = Z_WHATWG_URL_PROP_PATH_DEREF_P(ZEND_THIS);
const zval *query = Z_WHATWG_URL_PROP_QUERY_DEREF_P(ZEND_THIS);
const zval *fragment = Z_WHATWG_URL_PROP_FRAGMENT_DEREF_P(ZEND_THIS);

lxb_url_t *base_url = NULL;
if (base_url_zv != NULL) {
zend_argument_error(NULL, 1, "is not supported yet, and therefore, null must be passed");
RETURN_THROWS();
base_url = Z_URI_OBJECT_P(base_url_zv)->uri;
}

lxb_url_t *lexbor_url = php_uri_parser_whatwg_build_from_zval(
base_url, scheme, username, password, host, port, path, query, fragment,
errors
);
if (lexbor_url == NULL) {
RETURN_THROWS();
}

object_init_ex(return_value, php_uri_ce_whatwg_url);
php_uri_object *uri_object = Z_URI_OBJECT_P(return_value);
uri_object->parser = &php_uri_parser_whatwg;
uri_object->uri = lexbor_url;
}

PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser)
{
php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type);
Expand Down Expand Up @@ -1331,6 +1476,8 @@ static PHP_MINIT_FUNCTION(uri)
php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType();
php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType();

php_uri_ce_whatwg_url_builder = register_class_Uri_WhatWg_UrlBuilder();

php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url();
php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg;
php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri;
Expand Down
33 changes: 33 additions & 0 deletions ext/uri/php_uri.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,39 @@ enum UrlHostType
case Empty;
}

final class UrlBuilder
{
private string $scheme = "";
private ?string $username = null;
private ?string $password = null;
private ?string $host = null;
private ?int $port = null;
private string $path = "";
private ?string $query = null;
private ?string $fragment = null;

public function reset(): static {}

public function setScheme(string $scheme): static {}

public function setUsername(?string $username): static {}

public function setPassword(#[\SensitiveParameter] ?string $password): static {}

public function setHost(?string $host): static {}

public function setPort(?int $port): static {}

public function setPath(string $path): static {}

public function setQuery(?string $query): static {}

public function setFragment(?string $fragment): static {}

/** @param array $errors */
public function build(?\Uri\WhatWg\Url $baseUrl = null, &$errors = null): \Uri\WhatWg\Url {}
}

/** @strict-properties */
final readonly class Url
{
Expand Down
112 changes: 102 additions & 10 deletions ext/uri/php_uri_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading