cache only standard GET/HEAD by default
[m6w6/ext-http] / php_http_querystring.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 #include <php_variables.h>
16 #include <ext/spl/spl_array.h>
17
18 #ifdef PHP_HTTP_HAVE_ICONV
19 # undef PHP_ATOM_INC
20 # include <ext/iconv/php_iconv.h>
21 #endif
22
23 #ifdef PHP_HTTP_HAVE_ICONV
24 PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char *ie, const char *oe TSRMLS_DC)
25 {
26 HashPosition pos;
27 zval **entry = NULL;
28 char *xlate_str = NULL, *xkey;
29 size_t xlate_len = 0, xlen;
30 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
31
32 FOREACH_KEYVAL(pos, src, key, entry) {
33 if (key.type == HASH_KEY_IS_STRING) {
34 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
35 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe);
36 return FAILURE;
37 }
38 }
39
40 if (Z_TYPE_PP(entry) == IS_STRING) {
41 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
42 if (key.type == HASH_KEY_IS_STRING) {
43 efree(xkey);
44 }
45 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
46 return FAILURE;
47 }
48 if (key.type == HASH_KEY_IS_STRING) {
49 add_assoc_stringl_ex(dst, xkey, xlen+1, xlate_str, xlate_len, 0);
50 } else {
51 add_index_stringl(dst, key.num, xlate_str, xlate_len, 0);
52 }
53 } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
54 zval *subarray;
55
56 MAKE_STD_ZVAL(subarray);
57 array_init(subarray);
58 if (key.type == HASH_KEY_IS_STRING) {
59 add_assoc_zval_ex(dst, xkey, xlen+1, subarray);
60 } else {
61 add_index_zval(dst, key.num, subarray);
62 }
63 if (SUCCESS != php_http_querystring_xlate(subarray, *entry, ie, oe TSRMLS_CC)) {
64 if (key.type == HASH_KEY_IS_STRING) {
65 efree(xkey);
66 }
67 return FAILURE;
68 }
69 }
70
71 if (key.type == HASH_KEY_IS_STRING) {
72 efree(xkey);
73 }
74 }
75 return SUCCESS;
76 }
77 #endif /* HAVE_ICONV */
78
79 PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC)
80 {
81 /* enforce proper type */
82 if (Z_TYPE_P(qarray) != IS_ARRAY) {
83 convert_to_array(qarray);
84 }
85
86 /* modify qarray */
87 if (params) {
88 HashPosition pos;
89 HashTable *ptr;
90 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
91 zval **params_entry, **qarray_entry;
92 zval zv, *zv_ptr = NULL;
93
94 INIT_PZVAL(&zv);
95 ZVAL_NULL(&zv);
96
97 /* squeeze the hash out of the zval */
98 if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_class_entry TSRMLS_CC)) {
99 zv_ptr = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, params, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
100 ptr = Z_ARRVAL_P(zv_ptr);
101 } else if (Z_TYPE_P(params) == IS_OBJECT || Z_TYPE_P(params) == IS_ARRAY) {
102 ptr = HASH_OF(params);
103 } else {
104 zv_ptr = php_http_ztyp(IS_STRING, params);
105 array_init(&zv);
106 php_default_treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(zv_ptr)), &zv TSRMLS_CC);
107 zval_ptr_dtor(&zv_ptr);
108 zv_ptr = NULL;
109 ptr = Z_ARRVAL(zv);
110 }
111
112 FOREACH_HASH_KEYVAL(pos, ptr, key, params_entry) {
113 /* only public properties */
114 if (key.type != HASH_KEY_IS_STRING || *key.str) {
115 if (Z_TYPE_PP(params_entry) == IS_NULL) {
116 /*
117 * delete
118 */
119 if (key.type == HASH_KEY_IS_STRING) {
120 zend_hash_del(Z_ARRVAL_P(qarray), key.str, key.len);
121 } else {
122 zend_hash_index_del(Z_ARRVAL_P(qarray), key.num);
123 }
124 } else if ( ((key.type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &qarray_entry)))
125 || ((key.type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), key.num, (void *) &qarray_entry)))) {
126 /*
127 * update
128 */
129 zval equal, *entry = NULL;
130
131 /* recursive */
132 if (Z_TYPE_PP(params_entry) == IS_ARRAY || Z_TYPE_PP(params_entry) == IS_OBJECT) {
133 entry = php_http_zsep(1, IS_ARRAY, *qarray_entry);
134 php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
135 } else if ((FAILURE == is_equal_function(&equal, *qarray_entry, *params_entry TSRMLS_CC)) || !Z_BVAL(equal)) {
136 Z_ADDREF_PP(params_entry);
137 entry = *params_entry;
138 }
139
140 if (entry) {
141 if (key.type == HASH_KEY_IS_STRING) {
142 zend_hash_update(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &entry, sizeof(zval *), NULL);
143 } else {
144 zend_hash_index_update(Z_ARRVAL_P(qarray), key.num, (void *) &entry, sizeof(zval *), NULL);
145 }
146 }
147 } else {
148 zval *entry;
149 /*
150 * add
151 */
152 if (Z_TYPE_PP(params_entry) == IS_OBJECT) {
153 MAKE_STD_ZVAL(entry);
154 array_init(entry);
155 php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
156 } else {
157 Z_ADDREF_PP(params_entry);
158 entry = *params_entry;
159 }
160 if (key.type == HASH_KEY_IS_STRING) {
161 add_assoc_zval_ex(qarray, key.str, key.len, entry);
162 } else {
163 add_index_zval(qarray, key.num, entry);
164 }
165 }
166 }
167 }
168 /* clean up */
169 if (zv_ptr) {
170 zval_ptr_dtor(&zv_ptr);
171 }
172 zval_dtor(&zv);
173 }
174
175 /* serialize to string */
176 if (outstring) {
177 char *s;
178 size_t l;
179
180 if (SUCCESS == php_http_url_encode_hash(Z_ARRVAL_P(qarray), NULL, 0, &s, &l TSRMLS_CC)) {
181 zval_dtor(outstring);
182 ZVAL_STRINGL(outstring, s, l, 0);
183 } else {
184 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to encode query string");
185 return FAILURE;
186 }
187 }
188
189 return SUCCESS;
190 }
191
192 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpQueryString, method, 0, req_args)
193 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpQueryString, method, 0)
194 #define PHP_HTTP_QUERYSTRING_ME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, method), visibility)
195 #define PHP_HTTP_QUERYSTRING_GME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, __getter), visibility)
196
197 PHP_HTTP_BEGIN_ARGS(__construct, 0)
198 PHP_HTTP_ARG_VAL(params, 0)
199 PHP_HTTP_END_ARGS;
200
201 PHP_HTTP_EMPTY_ARGS(getGlobalInstance);
202
203 PHP_HTTP_EMPTY_ARGS(toArray);
204 PHP_HTTP_EMPTY_ARGS(toString);
205
206 PHP_HTTP_BEGIN_ARGS(get, 0)
207 PHP_HTTP_ARG_VAL(name, 0)
208 PHP_HTTP_ARG_VAL(type, 0)
209 PHP_HTTP_ARG_VAL(defval, 0)
210 PHP_HTTP_ARG_VAL(delete, 0)
211 PHP_HTTP_END_ARGS;
212
213 PHP_HTTP_BEGIN_ARGS(set, 1)
214 PHP_HTTP_ARG_VAL(params, 0)
215 PHP_HTTP_END_ARGS;
216
217 PHP_HTTP_BEGIN_ARGS(mod, 0)
218 PHP_HTTP_ARG_VAL(params, 0)
219 PHP_HTTP_END_ARGS;
220
221 PHP_HTTP_BEGIN_ARGS(__getter, 1)
222 PHP_HTTP_ARG_VAL(name, 0)
223 PHP_HTTP_ARG_VAL(defval, 0)
224 PHP_HTTP_ARG_VAL(delete, 0)
225 PHP_HTTP_END_ARGS;
226
227 #ifdef PHP_HTTP_HAVE_ICONV
228 PHP_HTTP_BEGIN_ARGS(xlate, 2)
229 PHP_HTTP_ARG_VAL(from_encoding, 0)
230 PHP_HTTP_ARG_VAL(to_encoding, 0)
231 PHP_HTTP_END_ARGS;
232 #endif
233
234 PHP_HTTP_EMPTY_ARGS(serialize);
235 PHP_HTTP_BEGIN_ARGS(unserialize, 1)
236 PHP_HTTP_ARG_VAL(serialized, 0)
237 PHP_HTTP_END_ARGS;
238
239 PHP_HTTP_BEGIN_ARGS(offsetGet, 1)
240 PHP_HTTP_ARG_VAL(offset, 0)
241 PHP_HTTP_END_ARGS;
242
243 PHP_HTTP_BEGIN_ARGS(offsetSet, 2)
244 PHP_HTTP_ARG_VAL(offset, 0)
245 PHP_HTTP_ARG_VAL(value, 0)
246 PHP_HTTP_END_ARGS;
247
248 PHP_HTTP_BEGIN_ARGS(offsetExists, 1)
249 PHP_HTTP_ARG_VAL(offset, 0)
250 PHP_HTTP_END_ARGS;
251
252 PHP_HTTP_BEGIN_ARGS(offsetUnset, 1)
253 PHP_HTTP_ARG_VAL(offset, 0)
254 PHP_HTTP_END_ARGS;
255
256 PHP_HTTP_EMPTY_ARGS(getIterator);
257
258 zend_class_entry *php_http_querystring_class_entry;
259 zend_function_entry php_http_querystring_method_entry[] = {
260 PHP_HTTP_QUERYSTRING_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
261
262 PHP_HTTP_QUERYSTRING_ME(toArray, ZEND_ACC_PUBLIC)
263 PHP_HTTP_QUERYSTRING_ME(toString, ZEND_ACC_PUBLIC)
264 ZEND_MALIAS(HttpQueryString, __toString, toString, PHP_HTTP_ARGS(HttpQueryString, toString), ZEND_ACC_PUBLIC)
265
266 PHP_HTTP_QUERYSTRING_ME(get, ZEND_ACC_PUBLIC)
267 PHP_HTTP_QUERYSTRING_ME(set, ZEND_ACC_PUBLIC)
268 PHP_HTTP_QUERYSTRING_ME(mod, ZEND_ACC_PUBLIC)
269
270 PHP_HTTP_QUERYSTRING_GME(getBool, ZEND_ACC_PUBLIC)
271 PHP_HTTP_QUERYSTRING_GME(getInt, ZEND_ACC_PUBLIC)
272 PHP_HTTP_QUERYSTRING_GME(getFloat, ZEND_ACC_PUBLIC)
273 PHP_HTTP_QUERYSTRING_GME(getString, ZEND_ACC_PUBLIC)
274 PHP_HTTP_QUERYSTRING_GME(getArray, ZEND_ACC_PUBLIC)
275 PHP_HTTP_QUERYSTRING_GME(getObject, ZEND_ACC_PUBLIC)
276
277 PHP_HTTP_QUERYSTRING_ME(getIterator, ZEND_ACC_PUBLIC)
278
279 PHP_HTTP_QUERYSTRING_ME(getGlobalInstance, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
280 #ifdef PHP_HTTP_HAVE_ICONV
281 PHP_HTTP_QUERYSTRING_ME(xlate, ZEND_ACC_PUBLIC)
282 #endif
283
284 /* Implements Serializable */
285 PHP_HTTP_QUERYSTRING_ME(serialize, ZEND_ACC_PUBLIC)
286 PHP_HTTP_QUERYSTRING_ME(unserialize, ZEND_ACC_PUBLIC)
287
288 /* Implements ArrayAccess */
289 PHP_HTTP_QUERYSTRING_ME(offsetGet, ZEND_ACC_PUBLIC)
290 PHP_HTTP_QUERYSTRING_ME(offsetSet, ZEND_ACC_PUBLIC)
291 PHP_HTTP_QUERYSTRING_ME(offsetExists, ZEND_ACC_PUBLIC)
292 PHP_HTTP_QUERYSTRING_ME(offsetUnset, ZEND_ACC_PUBLIC)
293
294 EMPTY_FUNCTION_ENTRY
295 };
296
297 PHP_MINIT_FUNCTION(http_querystring)
298 {
299 PHP_HTTP_REGISTER_CLASS(http, QueryString, http_querystring, php_http_object_class_entry, 0);
300
301 zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 3, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate);
302
303 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
304 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("queryArray"), ZEND_ACC_PRIVATE TSRMLS_CC);
305
306 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_BOOL"), PHP_HTTP_QUERYSTRING_TYPE_BOOL TSRMLS_CC);
307 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_INT"), PHP_HTTP_QUERYSTRING_TYPE_INT TSRMLS_CC);
308 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_FLOAT"), PHP_HTTP_QUERYSTRING_TYPE_FLOAT TSRMLS_CC);
309 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_STRING"), PHP_HTTP_QUERYSTRING_TYPE_STRING TSRMLS_CC);
310 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_ARRAY"), PHP_HTTP_QUERYSTRING_TYPE_ARRAY TSRMLS_CC);
311 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_OBJECT"), PHP_HTTP_QUERYSTRING_TYPE_OBJECT TSRMLS_CC);
312
313 return SUCCESS;
314 }
315
316 #define QS_MERGE 1
317
318 static inline void php_http_querystring_set(zval *instance, zval *params, int flags TSRMLS_DC)
319 {
320 zval *qa;
321
322 if (flags & QS_MERGE) {
323 qa = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
324 } else {
325 MAKE_STD_ZVAL(qa);
326 array_init(qa);
327 }
328
329 php_http_querystring_update(qa, params, NULL TSRMLS_CC);
330 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), qa TSRMLS_CC);
331 zval_ptr_dtor(&qa);
332 }
333
334 static inline void php_http_querystring_str(zval *instance, zval *return_value TSRMLS_DC)
335 {
336 zval *qa = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC);
337
338 if (Z_TYPE_P(qa) == IS_ARRAY) {
339 php_http_querystring_update(qa, NULL, return_value TSRMLS_CC);
340 } else {
341 RETURN_EMPTY_STRING();
342 }
343 }
344
345 static inline void php_http_querystring_get(zval *this_ptr, int type, char *name, uint name_len, zval *defval, zend_bool del, zval *return_value TSRMLS_DC)
346 {
347 zval **arrval, *qarray = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
348
349 if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_symtable_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
350 if (type) {
351 zval *value = php_http_ztyp(type, *arrval);
352 RETVAL_ZVAL(value, 1, 1);
353 } else {
354 RETVAL_ZVAL(*arrval, 1, 0);
355 }
356
357 if (del) {
358 zval *delarr;
359
360 MAKE_STD_ZVAL(delarr);
361 array_init(delarr);
362 add_assoc_null_ex(delarr, name, name_len + 1);
363 php_http_querystring_set(this_ptr, delarr, QS_MERGE TSRMLS_CC);
364 zval_ptr_dtor(&delarr);
365 }
366 } else if(defval) {
367 RETURN_ZVAL(defval, 1, 0);
368 }
369 }
370 PHP_METHOD(HttpQueryString, __construct)
371 {
372 zval *params = NULL;
373
374 with_error_handling(EH_THROW, php_http_exception_class_entry) {
375 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &params)) {
376 with_error_handling(EH_THROW, php_http_exception_class_entry) {
377 php_http_querystring_set(getThis(), params, 0 TSRMLS_CC);
378 } end_error_handling();
379 }
380 } end_error_handling();
381 }
382
383 PHP_METHOD(HttpQueryString, getGlobalInstance)
384 {
385 with_error_handling(EH_THROW, php_http_exception_class_entry) {
386 if (SUCCESS == zend_parse_parameters_none()) {
387 with_error_handling(EH_THROW, php_http_exception_class_entry) {
388 zval *instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0, NULL TSRMLS_CC);
389
390 if (Z_TYPE_P(instance) != IS_OBJECT) {
391 zval **_GET = NULL;
392
393 zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC);
394
395 if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET))
396 && (Z_TYPE_PP(_GET) == IS_ARRAY)
397 ) {
398 MAKE_STD_ZVAL(instance);
399 ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0);
400
401 SEPARATE_ZVAL_TO_MAKE_IS_REF(_GET);
402 convert_to_array(*_GET);
403 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), *_GET TSRMLS_CC);
404
405 zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC);
406 zval_ptr_dtor(&instance);
407 } else {
408 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET array");
409 }
410 }
411 RETVAL_ZVAL(instance, 1, 0);
412 } end_error_handling();
413 }
414 } end_error_handling();
415 }
416
417 PHP_METHOD(HttpQueryString, getIterator)
418 {
419 with_error_handling(EH_THROW, php_http_exception_class_entry) {
420 if (SUCCESS == zend_parse_parameters_none()) {
421 with_error_handling(EH_THROW, php_http_exception_class_entry) {
422 zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
423
424 object_init_ex(return_value, spl_ce_RecursiveArrayIterator);
425 zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa);
426 if (retval) {
427 zval_ptr_dtor(&retval);
428 }
429 } end_error_handling();
430 }
431 } end_error_handling();
432 }
433
434 PHP_METHOD(HttpQueryString, toString)
435 {
436 if (SUCCESS != zend_parse_parameters_none()) {
437 RETURN_FALSE;
438 }
439 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
440 }
441
442 PHP_METHOD(HttpQueryString, toArray)
443 {
444 if (SUCCESS == zend_parse_parameters_none()) {
445 RETURN_PROP(php_http_querystring_class_entry, "queryArray");
446 }
447 RETURN_FALSE;
448 }
449
450 PHP_METHOD(HttpQueryString, get)
451 {
452 char *name_str = NULL;
453 int name_len = 0;
454 long type = 0;
455 zend_bool del = 0;
456 zval *ztype = NULL, *defval = NULL;
457
458 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szzb", &name_str, &name_len, &ztype, &defval, &del)) {
459 if (name_str && name_len) {
460 if (ztype) {
461 if (Z_TYPE_P(ztype) == IS_LONG) {
462 type = Z_LVAL_P(ztype);
463 } else if(Z_TYPE_P(ztype) == IS_STRING) {
464 switch (Z_STRVAL_P(ztype)[0]) {
465 case 'B':
466 case 'b': type = PHP_HTTP_QUERYSTRING_TYPE_BOOL; break;
467 case 'L':
468 case 'l':
469 case 'I':
470 case 'i': type = PHP_HTTP_QUERYSTRING_TYPE_INT; break;
471 case 'd':
472 case 'D':
473 case 'F':
474 case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break;
475 case 'S':
476 case 's': type = PHP_HTTP_QUERYSTRING_TYPE_STRING; break;
477 case 'A':
478 case 'a': type = PHP_HTTP_QUERYSTRING_TYPE_ARRAY; break;
479 case 'O':
480 case 'o': type = PHP_HTTP_QUERYSTRING_TYPE_OBJECT; break;
481 }
482 }
483 }
484 php_http_querystring_get(getThis(), type, name_str, name_len, defval, del, return_value TSRMLS_CC);
485 } else {
486 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
487 }
488 }
489 }
490
491 PHP_METHOD(HttpQueryString, set)
492 {
493 zval *params;
494
495 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
496 RETURN_FALSE;
497 }
498
499 php_http_querystring_set(getThis(), params, QS_MERGE TSRMLS_CC);
500 RETVAL_ZVAL(getThis(), 1, 0);
501 }
502
503 PHP_METHOD(HttpQueryString, mod)
504 {
505 zval *params;
506
507 with_error_handling(EH_THROW, php_http_exception_class_entry) {
508 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
509 with_error_handling(EH_THROW, php_http_exception_class_entry) {
510 ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0);
511 php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC);
512 } end_error_handling();
513 }
514 } end_error_handling();
515 }
516
517 #define PHP_HTTP_QUERYSTRING_GETTER(method, TYPE) \
518 PHP_METHOD(HttpQueryString, method) \
519 { \
520 char *name; \
521 int name_len; \
522 zval *defval = NULL; \
523 zend_bool del = 0; \
524 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &name, &name_len, &defval, &del)) { \
525 php_http_querystring_get(getThis(), TYPE, name, name_len, defval, del, return_value TSRMLS_CC); \
526 } \
527 }
528 PHP_HTTP_QUERYSTRING_GETTER(getBool, IS_BOOL);
529 PHP_HTTP_QUERYSTRING_GETTER(getInt, IS_LONG);
530 PHP_HTTP_QUERYSTRING_GETTER(getFloat, IS_DOUBLE);
531 PHP_HTTP_QUERYSTRING_GETTER(getString, IS_STRING);
532 PHP_HTTP_QUERYSTRING_GETTER(getArray, IS_ARRAY);
533 PHP_HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
534
535 #ifdef PHP_HTTP_HAVE_ICONV
536 PHP_METHOD(HttpQueryString, xlate)
537 {
538 with_error_handling(EH_THROW, php_http_exception_class_entry) {
539 char *ie, *oe;
540 int ie_len, oe_len;
541
542 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
543 with_error_handling(EH_THROW, php_http_exception_class_entry) {
544 zval *na, *qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC));
545
546 MAKE_STD_ZVAL(na);
547 array_init(na);
548 if (SUCCESS == php_http_querystring_xlate(na, qa, ie, oe TSRMLS_CC)) {
549 php_http_querystring_set(getThis(), na, 0 TSRMLS_CC);
550 }
551
552 zval_ptr_dtor(&na);
553 zval_ptr_dtor(&qa);
554
555 RETVAL_ZVAL(getThis(), 1, 0);
556 } end_error_handling();
557 }
558 } end_error_handling();
559
560 }
561 #endif /* HAVE_ICONV */
562
563 PHP_METHOD(HttpQueryString, serialize)
564 {
565 if (SUCCESS != zend_parse_parameters_none()) {
566 RETURN_FALSE;
567 }
568 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
569 }
570
571 PHP_METHOD(HttpQueryString, unserialize)
572 {
573 zval *serialized;
574
575 with_error_handling(EH_THROW, php_http_exception_class_entry) {
576 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
577 with_error_handling(EH_THROW, php_http_exception_class_entry) {
578 if (Z_TYPE_P(serialized) == IS_STRING) {
579 php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC);
580 } else {
581 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Expected a string as parameter");
582 }
583 } end_error_handling();
584 }
585 } end_error_handling();
586 }
587
588 PHP_METHOD(HttpQueryString, offsetGet)
589 {
590 char *offset_str;
591 int offset_len;
592 zval **value;
593
594 if ((SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len))) {
595 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
596
597 if (Z_TYPE_P(qa) == IS_ARRAY
598 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
599 ) {
600 RETVAL_ZVAL(*value, 1, 0);
601 }
602 }
603 }
604
605 PHP_METHOD(HttpQueryString, offsetSet)
606 {
607 char *offset_str;
608 int offset_len;
609 zval *value;
610
611 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) {
612 zval *param;
613
614 MAKE_STD_ZVAL(param);
615 array_init(param);
616 Z_ADDREF_P(value);
617 add_assoc_zval_ex(param, offset_str, offset_len + 1, value);
618 php_http_querystring_set(getThis(), param, 0 TSRMLS_CC);
619 zval_ptr_dtor(&param);
620 }
621 }
622
623 PHP_METHOD(HttpQueryString, offsetExists)
624 {
625 char *offset_str;
626 int offset_len;
627 zval **value;
628
629 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
630 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
631
632 if (Z_TYPE_P(qa) == IS_ARRAY
633 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
634 && Z_TYPE_PP(value) != IS_NULL
635 ) {
636 RETURN_TRUE;
637 }
638 RETURN_FALSE;
639 }
640 }
641
642 PHP_METHOD(HttpQueryString, offsetUnset)
643 {
644 char *offset_str;
645 int offset_len;
646
647 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
648 zval *param;
649
650 MAKE_STD_ZVAL(param);
651 array_init(param);
652 add_assoc_null_ex(param, offset_str, offset_len + 1);
653 php_http_querystring_set(getThis(), param, QS_MERGE TSRMLS_CC);
654 zval_ptr_dtor(&param);
655 }
656 }
657
658
659 /*
660 * Local variables:
661 * tab-width: 4
662 * c-basic-offset: 4
663 * End:
664 * vim600: noet sw=4 ts=4 fdm=marker
665 * vim<600: noet sw=4 ts=4
666 */