| modification, are permitted provided that the conditions mentioned |
| in the accompanying LICENSE file are met. |
+--------------------------------------------------------------------+
- | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
+ | Copyright (c) 2004-2011, Michael Wallner <mike@php.net> |
+--------------------------------------------------------------------+
*/
-/* $Id$ */
+#include "php_http_api.h"
-#include "php_http.h"
-
-#include <main/php_variables.h>
+#include <php_variables.h>
#include <ext/spl/spl_array.h>
-#include <Zend/zend_interfaces.h>
#ifdef PHP_HTTP_HAVE_ICONV
# undef PHP_ATOM_INC
# include <ext/iconv/php_iconv.h>
#endif
+
+#define QS_MERGE 1
+
+static inline void php_http_querystring_set(zval *instance, zval *params, int flags TSRMLS_DC)
+{
+ zval *qa;
+
+ if (flags & QS_MERGE) {
+ qa = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_querystring_get_class_entry(), instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
+ } else {
+ MAKE_STD_ZVAL(qa);
+ array_init(qa);
+ }
+
+ php_http_querystring_update(qa, params, NULL TSRMLS_CC);
+ zend_update_property(php_http_querystring_get_class_entry(), instance, ZEND_STRL("queryArray"), qa TSRMLS_CC);
+ zval_ptr_dtor(&qa);
+}
+
+static inline void php_http_querystring_str(zval *instance, zval *return_value TSRMLS_DC)
+{
+ zval *qa = zend_read_property(php_http_querystring_get_class_entry(), instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC);
+
+ if (Z_TYPE_P(qa) == IS_ARRAY) {
+ php_http_querystring_update(qa, NULL, return_value TSRMLS_CC);
+ } else {
+ RETURN_EMPTY_STRING();
+ }
+}
+
+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)
+{
+ zval **arrval, *qarray = zend_read_property(php_http_querystring_get_class_entry(), getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
+
+ if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_symtable_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
+ if (type) {
+ zval *value = php_http_ztyp(type, *arrval);
+ RETVAL_ZVAL(value, 1, 1);
+ } else {
+ RETVAL_ZVAL(*arrval, 1, 0);
+ }
+
+ if (del) {
+ zval *delarr;
+
+ MAKE_STD_ZVAL(delarr);
+ array_init(delarr);
+ add_assoc_null_ex(delarr, name, name_len + 1);
+ php_http_querystring_set(this_ptr, delarr, QS_MERGE TSRMLS_CC);
+ zval_ptr_dtor(&delarr);
+ }
+ } else if(defval) {
+ RETURN_ZVAL(defval, 1, 0);
+ }
+}
+
#ifdef PHP_HTTP_HAVE_ICONV
PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char *ie, const char *oe TSRMLS_DC)
{
}
#endif /* HAVE_ICONV */
+PHP_HTTP_API STATUS php_http_querystring_ctor(zval *instance, zval *params TSRMLS_DC)
+{
+ php_http_querystring_set(instance, params, 0 TSRMLS_CC);
+ return SUCCESS;
+}
+
+static int apply_querystring(void *pData TSRMLS_DC)
+{
+ zval **val = pData;
+
+ if (Z_TYPE_PP(val) == IS_ARRAY) {
+ zval **zvalue;
+
+ if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("value"), (void *) &zvalue)) {
+ zval *tmp = *val;
+
+ Z_ADDREF_PP(zvalue);
+ *val = *zvalue;
+ zval_dtor(tmp);
+ Z_TYPE_P(tmp) = IS_NULL;
+ zval_ptr_dtor(&tmp);
+ }
+ }
+
+ return ZEND_HASH_APPLY_KEEP;
+}
+
+PHP_HTTP_API STATUS php_http_querystring_parse(HashTable *ht, const char *str, size_t len TSRMLS_DC)
+{
+ STATUS rv = FAILURE;
+ php_http_params_opts_t opts;
+ php_http_params_token_t psep = { ZEND_STRL("&") }, *psepp[] = { &psep, NULL };
+ php_http_params_token_t vsep = { ZEND_STRL("=") }, *vsepp[] = { &vsep, NULL };
+ const char *asi_str = NULL;
+ size_t asi_len = 0;
+
+ opts.input.str = estrndup(str, len);
+ opts.input.len = len;
+ opts.param = psepp;
+ opts.arg = NULL;
+ opts.val = vsepp;
+ opts.flags = PHP_HTTP_PARAMS_QUERY;
+
+ if (SUCCESS == php_http_ini_entry(ZEND_STRL("arg_separator.input"), &asi_str, &asi_len, 0 TSRMLS_CC) && asi_len) {
+ zval *arr;
+
+ MAKE_STD_ZVAL(arr);
+ array_init_size(arr, asi_len);
+
+ do {
+ add_next_index_stringl(arr, asi_str++, 1, 1);
+ } while (*asi_str);
+
+ opts.param = php_http_params_separator_init(arr TSRMLS_CC);
+
+ zval_ptr_dtor(&arr);
+ }
+
+ MAKE_STD_ZVAL(opts.defval);
+ ZVAL_NULL(opts.defval);
+
+ if (php_http_params_parse(ht, &opts TSRMLS_CC)) {
+ zend_hash_apply(ht, apply_querystring TSRMLS_CC);
+ rv = SUCCESS;
+ }
+
+ if (asi_len) {
+ php_http_params_separator_free(opts.param);
+ }
+
+ zval_ptr_dtor(&opts.defval);
+ efree(opts.input.str);
+ return rv;
+}
+
PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC)
{
/* enforce proper type */
ZVAL_NULL(&zv);
/* squeeze the hash out of the zval */
- if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_class_entry TSRMLS_CC)) {
- zv_ptr = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, params, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
+ if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_get_class_entry() TSRMLS_CC)) {
+ zv_ptr = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_get_class_entry(), params, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
ptr = Z_ARRVAL_P(zv_ptr);
} else if (Z_TYPE_P(params) == IS_OBJECT || Z_TYPE_P(params) == IS_ARRAY) {
ptr = HASH_OF(params);
} else {
zv_ptr = php_http_ztyp(IS_STRING, params);
array_init(&zv);
- php_default_treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(zv_ptr)), &zv TSRMLS_CC);
+ php_http_querystring_parse(Z_ARRVAL(zv), Z_STRVAL_P(zv_ptr), Z_STRLEN_P(zv_ptr) TSRMLS_CC);
zval_ptr_dtor(&zv_ptr);
zv_ptr = NULL;
ptr = Z_ARRVAL(zv);
}
}
} else {
+ zval *entry;
/*
* add
*/
if (Z_TYPE_PP(params_entry) == IS_OBJECT) {
- zval *new_array;
-
- MAKE_STD_ZVAL(new_array);
- array_init(new_array);
- php_http_querystring_update(new_array, *params_entry, NULL TSRMLS_CC);
- *params_entry = new_array;
+ MAKE_STD_ZVAL(entry);
+ array_init(entry);
+ php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
} else {
Z_ADDREF_PP(params_entry);
+ entry = *params_entry;
}
if (key.type == HASH_KEY_IS_STRING) {
- add_assoc_zval_ex(qarray, key.str, key.len, *params_entry);
+ add_assoc_zval_ex(qarray, key.str, key.len, entry);
} else {
- add_index_zval(qarray, key.num, *params_entry);
+ add_index_zval(qarray, key.num, entry);
}
}
}
PHP_HTTP_EMPTY_ARGS(getIterator);
-zend_class_entry *php_http_querystring_class_entry;
-zend_function_entry php_http_querystring_method_entry[] = {
+static zend_class_entry *php_http_querystring_class_entry;
+
+zend_class_entry *php_http_querystring_get_class_entry(void)
+{
+ return php_http_querystring_class_entry;
+}
+
+static zend_function_entry php_http_querystring_method_entry[] = {
PHP_HTTP_QUERYSTRING_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
PHP_HTTP_QUERYSTRING_ME(toArray, ZEND_ACC_PUBLIC)
PHP_MINIT_FUNCTION(http_querystring)
{
- PHP_HTTP_REGISTER_CLASS(http, QueryString, http_querystring, php_http_object_class_entry, 0);
+ PHP_HTTP_REGISTER_CLASS(http, QueryString, http_querystring, php_http_object_get_class_entry(), 0);
- zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 4, php_http_fluently_callable_class_entry, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate);
+ zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 3, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate);
zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("queryArray"), ZEND_ACC_PRIVATE TSRMLS_CC);
return SUCCESS;
}
-#define QS_MERGE 1
-
-static inline void php_http_querystring_set(zval *instance, zval *params, int flags TSRMLS_DC)
-{
- zval *qa;
-
- if (flags & QS_MERGE) {
- qa = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
- } else {
- MAKE_STD_ZVAL(qa);
- array_init(qa);
- }
-
- php_http_querystring_update(qa, params, NULL TSRMLS_CC);
- zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), qa TSRMLS_CC);
- zval_ptr_dtor(&qa);
-}
-
-static inline void php_http_querystring_str(zval *instance, zval *return_value TSRMLS_DC)
-{
- zval *qa = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC);
-
- if (Z_TYPE_P(qa) == IS_ARRAY) {
- php_http_querystring_update(qa, NULL, return_value TSRMLS_CC);
- } else {
- RETURN_EMPTY_STRING();
- }
-}
-
-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)
-{
- zval **arrval, *qarray = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
-
- if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
- if (type) {
- zval *value = php_http_ztyp(type, *arrval);
- RETVAL_ZVAL(value, 1, 1);
- } else {
- RETVAL_ZVAL(*arrval, 1, 0);
- }
-
- if (del) {
- zval *delarr;
-
- MAKE_STD_ZVAL(delarr);
- array_init(delarr);
- add_assoc_null_ex(delarr, name, name_len + 1);
- php_http_querystring_set(this_ptr, delarr, QS_MERGE TSRMLS_CC);
- zval_ptr_dtor(&delarr);
- }
- } else if(defval) {
- RETURN_ZVAL(defval, 1, 0);
- }
-}
PHP_METHOD(HttpQueryString, __construct)
{
zval *params = NULL;
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", ¶ms)) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
php_http_querystring_set(getThis(), params, 0 TSRMLS_CC);
} end_error_handling();
}
PHP_METHOD(HttpQueryString, getGlobalInstance)
{
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (SUCCESS == zend_parse_parameters_none()) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
zval *instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0, NULL TSRMLS_CC);
if (Z_TYPE_P(instance) != IS_OBJECT) {
PHP_METHOD(HttpQueryString, getIterator)
{
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (SUCCESS == zend_parse_parameters_none()) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
object_init_ex(return_value, spl_ce_RecursiveArrayIterator);
{
zval *params;
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶ms)) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0);
php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC);
} end_error_handling();
#ifdef PHP_HTTP_HAVE_ICONV
PHP_METHOD(HttpQueryString, xlate)
{
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
char *ie, *oe;
int ie_len, oe_len;
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
zval *na, *qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC));
MAKE_STD_ZVAL(na);
{
zval *serialized;
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
- with_error_handling(EH_THROW, php_http_exception_class_entry) {
+ with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
if (Z_TYPE_P(serialized) == IS_STRING) {
php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC);
} else {
zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
if (Z_TYPE_P(qa) == IS_ARRAY
- && SUCCESS == zend_hash_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
+ && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
) {
RETVAL_ZVAL(*value, 1, 0);
}
zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
if (Z_TYPE_P(qa) == IS_ARRAY
- && SUCCESS == zend_hash_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
+ && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
&& Z_TYPE_PP(value) != IS_NULL
) {
RETURN_TRUE;