From: Sara Golemon Date: Sat, 6 Sep 2003 00:35:21 +0000 (+0000) Subject: Introducing php_url_encode_hash_ex() internal function X-Git-Tag: RELEASE_0_7~213 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0be65c49d38b30bb6dadfa9cb805c39515e995f1;p=php Introducing php_url_encode_hash_ex() internal function and http_build_query() userspace function. --- diff --git a/NEWS b/NEWS index c81b0201b9..9d0629ac64 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ PHP NEWS . pg_version(). (Marcus) . dbase_get_header_info(). (Zak) . snmp_read_mib(). (Jani) + . http_build_query(). (Sara) - Added "resume_pos" context option to "ftp://" wrapper. (Sara) - Added optional parameter to OCIWriteTemporaryLob() to specify the type of LOB (Patch by Novicky Marek ). (Thies) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 13b034bcbe..c871821bfa 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -27,6 +27,7 @@ #include "internal_functions_registry.h" #include "php_standard.h" #include "php_math.h" +#include "http.h" #include "php_incomplete_class.h" #include "ext/standard/info.h" #include "ext/session/php_session.h" @@ -429,6 +430,7 @@ function_entry basic_functions[] = { PHP_FE(urldecode, NULL) PHP_FE(rawurlencode, NULL) PHP_FE(rawurldecode, NULL) + PHP_FE(http_build_query, NULL) #ifdef HAVE_SYMLINK PHP_FE(readlink, NULL) diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 51ef3e4cd2..9c85a29d79 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -307,6 +307,6 @@ PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32. incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c \ - filters.c proc_open.c sunfuncs.c streamsfuncs.c) + filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c) PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/standard/http.c b/ext/standard/http.c new file mode 100644 index 0000000000..8991cd1075 --- /dev/null +++ b/ext/standard/http.c @@ -0,0 +1,186 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 4 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2003 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "http.h" +#include "php_ini.h" +#include "url.h" + +#define URL_DEFAULT_ARG_SEP "&" + +/* {{{ php_url_encode_hash */ +PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, + const char *num_prefix, int num_prefix_len, + const char *key_prefix, int key_prefix_len, + const char *key_suffix, int key_suffix_len TSRMLS_DC) +{ + char *arg_sep = NULL, *key = NULL, *ekey, *newprefix, *p; + int arg_sep_len, key_len, ekey_len, key_type, newprefix_len; + ulong idx; + zval **zdata = NULL, *copyzval; + + if (!ht) { + return FAILURE; + } + + arg_sep = INI_STR("arg_separator.output"); + if (!arg_sep || !strlen(arg_sep)) { + arg_sep = URL_DEFAULT_ARG_SEP; + } + arg_sep_len = strlen(arg_sep); + + for(zend_hash_internal_pointer_reset(ht); + (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT; + zend_hash_move_forward(ht)) { + if (key_len && key[key_len-1] == '\0') { + /* We don't want that trailing NULL */ + key_len -= 1; + } + + if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array."); + return FAILURE; + } + if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) { + if (key_type == HASH_KEY_IS_STRING) { + ekey = php_url_encode(key, key_len, &ekey_len); + newprefix_len = key_suffix_len + ekey_len + key_prefix_len + 1; + newprefix = emalloc(newprefix_len + 1); + p = newprefix; + + if (key_prefix) { + memcpy(p, key_prefix, key_prefix_len); + p += key_prefix_len; + } + + memcpy(p, ekey, ekey_len); + p += ekey_len; + efree(ekey); + + if (key_suffix) { + memcpy(p, key_suffix, key_suffix_len); + p += key_suffix_len; + } + + *(p++) = '['; + *p = '\0'; + } else { + /* Is an integer key */ + ekey_len = spprintf(&ekey, 12, "%ld", idx); + newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 1; + newprefix = emalloc(newprefix_len + 1); + p = newprefix; + + if (key_prefix) { + memcpy(p, key_prefix, key_prefix_len); + p += key_prefix_len; + } + + memcpy(p, num_prefix, num_prefix_len); + p += num_prefix_len; + + memcpy(p, ekey, ekey_len); + p += ekey_len; + efree(ekey); + + if (key_suffix) { + memcpy(p, key_suffix, key_suffix_len); + p += key_suffix_len; + } + *(p++) = '['; + *p = '\0'; + } + php_url_encode_hash_ex(Z_ARRVAL_PP(zdata), formstr, NULL, 0, newprefix, newprefix_len, "]", 1 TSRMLS_CC); + efree(newprefix); + } else { + if (formstr->len) { + smart_str_appendl(formstr, arg_sep, arg_sep_len); + } + /* Simple key=value */ + smart_str_appendl(formstr, key_prefix, key_prefix_len); + if (key_type == HASH_KEY_IS_STRING) { + ekey = php_url_encode(key, key_len, &ekey_len); + smart_str_appendl(formstr, ekey, ekey_len); + efree(ekey); + } else { + /* Numeric key */ + if (num_prefix) { + smart_str_appendl(formstr, num_prefix, num_prefix_len); + } + ekey_len = spprintf(&ekey, 12, "%ld", idx); + smart_str_appendl(formstr, ekey, ekey_len); + efree(ekey); + } + smart_str_appendl(formstr, key_suffix, key_suffix_len); + smart_str_appendl(formstr, "=", 1); + switch (Z_TYPE_PP(zdata)) { + case IS_STRING: + ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); + break; + case IS_LONG: + ekey_len = spprintf(&ekey, 12, "%ld", idx); + break; + default: + /* fall back on convert to string */ + *copyzval = **zdata; + zval_copy_ctor(copyzval); + convert_to_string_ex(©zval); + ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); + zval_ptr_dtor(©zval); + } + smart_str_appendl(formstr, ekey, ekey_len); + efree(ekey); + } + } + + return SUCCESS; +} +/* }}} */ + +PHP_FUNCTION(http_build_query) +{ + zval *formdata; + char *prefix = NULL; + int prefix_len = 0; + smart_str formstr = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|s", &formdata, &prefix, &prefix_len) != SUCCESS) { + RETURN_FALSE; + } + + if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0 TSRMLS_CC) == FAILURE) { + if (formstr.c) { + efree(formstr.c); + } + RETURN_FALSE; + } + smart_str_0(&formstr); + RETURN_STRINGL(formstr.c, formstr.len, 0); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ + diff --git a/ext/standard/http.h b/ext/standard/http.h new file mode 100644 index 0000000000..589996249b --- /dev/null +++ b/ext/standard/http.h @@ -0,0 +1,35 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 4 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2003 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_HTTP_H +#define PHP_HTTP_H + +#include "php.h" +#include "php_smart_str.h" + +PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, + const char *num_prefix, int num_prefix_len, + const char *key_prefix, int key_prefix_len, + const char *key_suffix, int key_suffix_len TSRMLS_DC); +#define php_url_encode_hash(ht, formstr) php_url_encode_hash_ex((ht), (formstr), NULL, 0, NULL, 0, NULL, 0 TSRMLS_CC) + +PHP_FUNCTION(http_build_query); + +#endif