@@ -29,6 +29,7 @@ extern "C" {
29
29
#include " Zend/zend_enum.h"
30
30
#include " Zend/zend_interfaces.h"
31
31
#include " url_arginfo.h"
32
+ #include " ext/standard/url.h"
32
33
}
33
34
34
35
#include < ada/ada.h>
@@ -37,94 +38,187 @@ static zend_class_entry *url_ce;
37
38
static zend_class_entry *url_component_ce;
38
39
static zend_class_entry *url_parser_ce;
39
40
41
+ static php_url *parseUrlComponents (zend_string *url) {
42
+ ada::result<ada::url> ada_url = ada::parse<ada::url>(ZSTR_VAL (url));
43
+ if (!ada_url) {
44
+ return NULL ;
45
+ }
46
+
47
+ ada::url_components components = ada_url->get_components ();
48
+
49
+ php_url *result = (php_url*) ecalloc (1 , sizeof (php_url));
50
+
51
+ result->scheme = zend_string_init (ZSTR_VAL (url), components.protocol_end - 1 , false );
52
+
53
+ if (components.host_start < components.host_end ) {
54
+ result->host = zend_string_init (ZSTR_VAL (url) + components.host_start , components.host_end - components.host_start + 1 , false );
55
+ } else {
56
+ result->host = NULL ;
57
+ }
58
+
59
+ result->port = ada_url->has_port () ? components.port : 0 ;
60
+
61
+ if (components.protocol_end + 2 < components.username_end ) {
62
+ result->user = zend_string_init (ZSTR_VAL (url) + components.protocol_end + 2 , components.username_end - components.protocol_end - 2 , false );
63
+ } else {
64
+ result->user = NULL ;
65
+ }
66
+
67
+ if (components.host_start - components.username_end > 0 ) {
68
+ result->pass = zend_string_init (ZSTR_VAL (url) + components.username_end + 1 , components.host_start - components.username_end - 1 , false );
69
+ } else {
70
+ result->pass = NULL ;
71
+ }
72
+
73
+ size_t ends_at;
74
+ if (ada_url->has_search ()) {
75
+ ends_at = components.search_start ;
76
+ } else if (ada_url->has_hash ()) {
77
+ ends_at = components.hash_start ;
78
+ } else {
79
+ ends_at = components.pathname_start ;
80
+ }
81
+ result->path = zend_string_init (ZSTR_VAL (url) + components.pathname_start , ends_at - components.pathname_start , false );
82
+
83
+ if (!ada_url->has_search ()) {
84
+ result->query = NULL ;
85
+ } else {
86
+ ends_at = ada_url->has_hash () ? components.hash_start : ZSTR_LEN (url);
87
+ if (ends_at - components.search_start <= 1 ) {
88
+ result->query = NULL ;
89
+ } else {
90
+ result->query = zend_string_init (ZSTR_VAL (url) + components.search_start , ends_at - components.search_start , false );
91
+ }
92
+ }
93
+
94
+ if (ada_url->has_hash () && (ZSTR_LEN (url) - components.hash_start > 1 )) {
95
+ result->fragment = zend_string_init (ZSTR_VAL (url) + components.hash_start + 1 , ZSTR_LEN (url) - components.hash_start - 1 , false );
96
+ } else {
97
+ result->fragment = NULL ;
98
+ }
99
+
100
+ return result;
101
+ }
102
+
40
103
void parseUrlComponentsArray (zend_string *url, zval *return_value)
41
104
{
42
- std::string_view protocol, hostname, username, password, port, path, query, fragment;
105
+ php_url *components;
106
+ zval tmp;
43
107
44
- ada::result<ada::url_aggregator> ada_url = ada::parse<ada::url_aggregator>( ZSTR_VAL ( url) );
45
- if (!ada_url ) {
108
+ components = parseUrlComponents ( url);
109
+ if (!components ) {
46
110
RETURN_NULL ();
47
111
}
48
112
49
- protocol = ada_url->get_protocol ();
50
- hostname = ada_url->get_hostname ();
51
- port = ada_url->get_port ();
52
- username = ada_url->get_username ();
53
- password = ada_url->get_password ();
54
- path = ada_url->get_protocol ();
55
- query = ada_url->get_search ();
56
- fragment = ada_url->get_hash ();
57
-
58
113
array_init (return_value);
59
- add_assoc_stringl (return_value," scheme" ,protocol.data (), protocol.length ()-1 );
60
- add_assoc_stringl (return_value," host" , hostname.data (), hostname.length ());
61
- add_assoc_stringl (return_value, " port" , port.data (), port.length ());
62
- add_assoc_stringl (return_value, " user" , username.data (), username.length ());
63
- add_assoc_stringl (return_value, " password" , password.data (), password.length ());
64
- add_assoc_stringl (return_value, " path" , path.data (), path.length ());
65
- add_assoc_stringl (return_value, " query" , query.data (), query.length ());
66
- add_assoc_stringl (return_value, " fragment" , fragment.data (), fragment.length ());
114
+
115
+ if (components->scheme != NULL ) {
116
+ ZVAL_STR_COPY (&tmp, components->scheme );
117
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_SCHEME), &tmp);
118
+ }
119
+
120
+ if (components->host != NULL ) {
121
+ ZVAL_STR_COPY (&tmp, components->host );
122
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_HOST), &tmp);
123
+ }
124
+
125
+ if (components->port > 0 ) {
126
+ ZVAL_LONG (&tmp, components->port );
127
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_PORT), &tmp);
128
+ }
129
+
130
+ if (components->user != NULL ) {
131
+ ZVAL_STR_COPY (&tmp, components->user );
132
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_USER), &tmp);
133
+ }
134
+
135
+ if (components->pass != NULL ) {
136
+ ZVAL_STR_COPY (&tmp, components->pass );
137
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_PASS), &tmp);
138
+ }
139
+
140
+ if (ZSTR_LEN (components->path )) {
141
+ ZVAL_STR_COPY (&tmp, components->path );
142
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_PATH), &tmp);
143
+ }
144
+
145
+ if (components->query != NULL ) {
146
+ ZVAL_STR_COPY (&tmp, components->query );
147
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_QUERY), &tmp);
148
+ }
149
+
150
+ if (components->fragment != NULL ) {
151
+ ZVAL_STR_COPY (&tmp, components->fragment );
152
+ zend_hash_add_new (Z_ARRVAL_P (return_value), ZSTR_KNOWN (ZEND_STR_FRAGMENT), &tmp);
153
+ }
154
+
155
+ php_url_free (components);
67
156
}
68
157
69
158
void parseUrlComponentsObject (zend_string *url, zval *return_value)
70
159
{
71
- std::string_view protocol, hostname, username, password, port, path, query, fragment ;
160
+ php_url *components ;
72
161
73
- ada::result<ada::url_aggregator> ada_url = ada::parse<ada::url_aggregator>( ZSTR_VAL ( url) );
74
- if (!ada_url ) {
162
+ components = parseUrlComponents ( url);
163
+ if (!components ) {
75
164
RETURN_NULL ();
76
165
}
77
166
78
- protocol = ada_url->get_protocol ();
79
- hostname = ada_url->get_hostname ();
80
- port = ada_url->get_port ();
81
- username = ada_url->get_username ();
82
- password = ada_url->get_password ();
83
- path = ada_url->get_protocol ();
84
- query = ada_url->get_search ();
85
- fragment = ada_url->get_hash ();
86
-
87
167
object_init_ex (return_value, url_ce);
88
- zend_update_property_stringl (
89
- url_ce, Z_OBJ_P (return_value),
90
- " scheme" , sizeof (" scheme" )-1 ,
91
- protocol.data (), protocol.length ()-1
92
- );
93
- zend_update_property_stringl (
168
+ zend_update_property_str (
94
169
url_ce, Z_OBJ_P (return_value),
95
- " host " , sizeof ( " host " )- 1 ,
96
- hostname. data (), hostname. length ()
170
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_SCHEME)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_SCHEME)) ,
171
+ components-> scheme ? components-> scheme : ZSTR_EMPTY_ALLOC ()
97
172
);
98
- zend_update_property_stringl (
173
+ zend_update_property_str (
99
174
url_ce, Z_OBJ_P (return_value),
100
- " port " , sizeof ( " port " )- 1 ,
101
- port. data (), port. length ()
175
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_HOST)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_HOST)) ,
176
+ components-> host ? components-> host : ZSTR_EMPTY_ALLOC ()
102
177
);
103
- zend_update_property_stringl (
178
+ if (components->port > 0 ) {
179
+ zend_update_property_long (
180
+ url_ce, Z_OBJ_P (return_value),
181
+ ZSTR_VAL (ZSTR_KNOWN (ZEND_STR_PORT)), ZSTR_LEN (ZSTR_KNOWN (ZEND_STR_PORT)),
182
+ components->port
183
+ );
184
+ } else {
185
+ zend_update_property_null (
186
+ url_ce, Z_OBJ_P (return_value),
187
+ ZSTR_VAL (ZSTR_KNOWN (ZEND_STR_PORT)), ZSTR_LEN (ZSTR_KNOWN (ZEND_STR_PORT))
188
+ );
189
+ }
190
+
191
+ zend_update_property_str (
104
192
url_ce, Z_OBJ_P (return_value),
105
- " user " , sizeof ( " user " )- 1 ,
106
- username. data (), username. length ()
193
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_USER)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_USER)) ,
194
+ components-> user ? components-> user : ZSTR_EMPTY_ALLOC ()
107
195
);
108
- zend_update_property_stringl (
196
+
197
+ zend_update_property_str (
109
198
url_ce, Z_OBJ_P (return_value),
110
- " password " , sizeof ( " password " )- 1 ,
111
- password. data (), password. length ()
199
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_PASSWORD)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_PASSWORD)) ,
200
+ components-> pass ? components-> pass : ZSTR_EMPTY_ALLOC ()
112
201
);
113
- zend_update_property_stringl (
202
+
203
+ zend_update_property_str (
114
204
url_ce, Z_OBJ_P (return_value),
115
- " path " , sizeof ( " path " )- 1 ,
116
- path. data (), path. length ()
205
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_PATH)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_PATH)) ,
206
+ components-> path ? components-> path : ZSTR_EMPTY_ALLOC ()
117
207
);
118
- zend_update_property_stringl (
208
+
209
+ zend_update_property_str (
119
210
url_ce, Z_OBJ_P (return_value),
120
- " query " , sizeof ( " query " )- 1 ,
121
- query. data (), query. length ()
211
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_QUERY)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_QUERY)) ,
212
+ components-> query ? components-> query : ZSTR_EMPTY_ALLOC ()
122
213
);
123
- zend_update_property_stringl (
214
+
215
+ zend_update_property_str (
124
216
url_ce, Z_OBJ_P (return_value),
125
- " fragment " , sizeof ( " fragment " )- 1 ,
126
- fragment. data (), fragment. length ()
217
+ ZSTR_VAL ( ZSTR_KNOWN (ZEND_STR_FRAGMENT)), ZSTR_LEN ( ZSTR_KNOWN (ZEND_STR_FRAGMENT)) ,
218
+ components-> fragment ? components-> fragment : ZSTR_EMPTY_ALLOC ()
127
219
);
220
+
221
+ php_url_free (components);
128
222
}
129
223
130
224
PHP_METHOD (Url_Url, __construct)
0 commit comments