From a603c06e2e3db50e1752876a8146eaa08b113269 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 5 Dec 2019 10:28:41 +0100 Subject: [PATCH] Support "string or array" in zpp This is one of our more common argument unions. Usage is just prototyped in a few places, certainly not a full conversion. I'm removing the str_replace.phpt test, because aparently it was split up into smaller tests at some point, but the original has not been removed. Closes GH-4970. --- Zend/zend_API.h | 25 + ext/standard/basic_functions.stub.php | 13 +- ext/standard/basic_functions_arginfo.h | 6 +- ext/standard/string.c | 117 +-- ext/standard/tests/strings/str_replace.phpt | 932 ------------------ .../tests/strings/str_replace_basic.phpt | 10 +- .../tests/strings/str_replace_variation3.phpt | 20 +- 7 files changed, 106 insertions(+), 1017 deletions(-) delete mode 100644 ext/standard/tests/strings/str_replace.phpt diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 08a5f2aa40..c822791850 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1129,6 +1129,7 @@ static zend_always_inline zval *zend_try_array_init(zval *zv) _(Z_EXPECTED_OBJECT, "object") \ _(Z_EXPECTED_DOUBLE, "float") \ _(Z_EXPECTED_NUMBER, "int or float") \ + _(Z_EXPECTED_STRING_OR_ARRAY, "string or array") \ #define Z_EXPECTED_TYPE_ENUM(id, str) id, #define Z_EXPECTED_TYPE_STR(id, str) str, @@ -1535,6 +1536,14 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *e #define Z_PARAM_VARIADIC(spec, dest, dest_num) \ Z_PARAM_VARIADIC_EX(spec, dest, dest_num, 0) +#define Z_PARAM_STR_OR_ARRAY_HT(dest_str, dest_ht) \ + Z_PARAM_PROLOGUE(0, 0); \ + if (UNEXPECTED(!zend_parse_arg_str_or_array_ht(_arg, &dest_str, &dest_ht))) { \ + _expected_type = Z_EXPECTED_STRING_OR_ARRAY; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + break; \ + } + /* End of new parameter parsing API */ /* Inlined implementations shared by new and old parameter parsing APIs */ @@ -1753,6 +1762,22 @@ static zend_always_inline void zend_parse_arg_zval_deref(zval *arg, zval **dest, *dest = (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) ? NULL : arg; } +static zend_always_inline int zend_parse_arg_str_or_array_ht( + zval *arg, zend_string **dest_str, HashTable **dest_ht) +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { + *dest_str = Z_STR_P(arg); + *dest_ht = NULL; + } else if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) { + *dest_ht = Z_ARRVAL_P(arg); + *dest_str = NULL; + } else { + *dest_ht = NULL; + return zend_parse_arg_str_slow(arg, dest_str); + } + return 1; +} + END_EXTERN_C() #endif /* ZEND_API_H */ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 759d4f0429..8a047d1460 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -580,12 +580,11 @@ function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"): function substr(string $str, int $start, ?int $length = null): string|false {} /** - * @param mixed $str - * @param mixed $replace * @param mixed $start * @param mixed $length */ -function substr_replace($str, $replace, $start, $length = UNKNOWN): string|array|false {} +function substr_replace( + string|array $str, string|array $replace, $start, $length = UNKNOWN): string|array|false {} function quotemeta(string $str): string {} @@ -620,18 +619,18 @@ function stripslashes(string $str): string {} /** * @param string|array $search * @param string|array $replace - * @param string|array $subject * @param int $replace_count */ -function str_replace($search, $replace, $subject, &$replace_count = UNKNOWN): string|array {} +function str_replace( + $search, $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} /** * @param string|array $search * @param string|array $replace - * @param string|array $subject * @param int $replace_count */ -function str_ireplace($search, $replace, $subject, &$replace_count = UNKNOWN): string|array {} +function str_ireplace( + $search, $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} function hebrev(string $str, int $max_chars_per_line = 0): string {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 19e714b1d7..00d91461a9 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -917,8 +917,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr, 0, 2, MAY_BE_STRING|MAY_ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, str) - ZEND_ARG_INFO(0, replace) + ZEND_ARG_TYPE_MASK(0, str, MAY_BE_STRING|MAY_BE_ARRAY) + ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_STRING|MAY_BE_ARRAY) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, length) ZEND_END_ARG_INFO() @@ -970,7 +970,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_str_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY) ZEND_ARG_INFO(0, search) ZEND_ARG_INFO(0, replace) - ZEND_ARG_INFO(0, subject) + ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY) ZEND_ARG_INFO(1, replace_count) ZEND_END_ARG_INFO() diff --git a/ext/standard/string.c b/ext/standard/string.c index c6de4dba98..84159cb7b7 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2258,37 +2258,30 @@ truncate_len: Replaces part of a string with another string */ PHP_FUNCTION(substr_replace) { - zval *str; + zend_string *str, *repl_str; + HashTable *str_ht, *repl_ht; zval *from; zval *len = NULL; - zval *repl; zend_long l = 0; zend_long f; int argc = ZEND_NUM_ARGS(); zend_string *result; HashPosition from_idx, repl_idx, len_idx; - zval *tmp_str = NULL, *tmp_from = NULL, *tmp_repl = NULL, *tmp_len= NULL; + zval *tmp_str = NULL, *tmp_repl, *tmp_from = NULL, *tmp_len= NULL; ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_ZVAL(str) - Z_PARAM_ZVAL(repl) + Z_PARAM_STR_OR_ARRAY_HT(str, str_ht) + Z_PARAM_STR_OR_ARRAY_HT(repl_str, repl_ht) Z_PARAM_ZVAL(from) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(len) ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(str) != IS_ARRAY) { - convert_to_string_ex(str); - } - if (Z_TYPE_P(repl) != IS_ARRAY) { - convert_to_string_ex(repl); - } if (Z_TYPE_P(from) != IS_ARRAY) { convert_to_long_ex(from); - } - - if (EG(exception)) { - return; + if (EG(exception)) { + return; + } } if (argc > 3) { @@ -2297,92 +2290,90 @@ PHP_FUNCTION(substr_replace) l = Z_LVAL_P(len); } } else { - if (Z_TYPE_P(str) != IS_ARRAY) { - l = Z_STRLEN_P(str); + if (str) { + l = ZSTR_LEN(str); } } - if (Z_TYPE_P(str) == IS_STRING) { + if (str) { if ( (argc == 3 && Z_TYPE_P(from) == IS_ARRAY) || (argc == 4 && Z_TYPE_P(from) != Z_TYPE_P(len)) ) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should be of same type - numerical or array "); - RETURN_STR_COPY(Z_STR_P(str)); + RETURN_STR_COPY(str); } if (argc == 4 && Z_TYPE_P(from) == IS_ARRAY) { if (zend_hash_num_elements(Z_ARRVAL_P(from)) != zend_hash_num_elements(Z_ARRVAL_P(len))) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should have the same number of elements"); - RETURN_STR_COPY(Z_STR_P(str)); + RETURN_STR_COPY(str); } } } - if (Z_TYPE_P(str) != IS_ARRAY) { + if (str) { if (Z_TYPE_P(from) != IS_ARRAY) { - zend_string *repl_str; - zend_string *tmp_repl_str = NULL; f = Z_LVAL_P(from); /* if "from" position is negative, count start position from the end * of the string */ if (f < 0) { - f = (zend_long)Z_STRLEN_P(str) + f; + f = (zend_long)ZSTR_LEN(str) + f; if (f < 0) { f = 0; } - } else if ((size_t)f > Z_STRLEN_P(str)) { - f = Z_STRLEN_P(str); + } else if ((size_t)f > ZSTR_LEN(str)) { + f = ZSTR_LEN(str); } /* if "length" position is negative, set it to the length * needed to stop that many chars from the end of the string */ if (l < 0) { - l = ((zend_long)Z_STRLEN_P(str) - f) + l; + l = ((zend_long)ZSTR_LEN(str) - f) + l; if (l < 0) { l = 0; } } - if ((size_t)l > Z_STRLEN_P(str) || (l < 0 && (size_t)(-l) > Z_STRLEN_P(str))) { - l = Z_STRLEN_P(str); + if ((size_t)l > ZSTR_LEN(str) || (l < 0 && (size_t)(-l) > ZSTR_LEN(str))) { + l = ZSTR_LEN(str); } - if ((f + l) > (zend_long)Z_STRLEN_P(str)) { - l = Z_STRLEN_P(str) - f; + if ((f + l) > (zend_long)ZSTR_LEN(str)) { + l = ZSTR_LEN(str) - f; } - if (Z_TYPE_P(repl) == IS_ARRAY) { + + zend_string *tmp_repl_str = NULL; + if (repl_ht) { repl_idx = 0; - while (repl_idx < Z_ARRVAL_P(repl)->nNumUsed) { - tmp_repl = &Z_ARRVAL_P(repl)->arData[repl_idx].val; + while (repl_idx < repl_ht->nNumUsed) { + tmp_repl = &repl_ht->arData[repl_idx].val; if (Z_TYPE_P(tmp_repl) != IS_UNDEF) { break; } repl_idx++; } - if (repl_idx < Z_ARRVAL_P(repl)->nNumUsed) { + if (repl_idx < repl_ht->nNumUsed) { repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str); } else { repl_str = STR_EMPTY_ALLOC(); } - } else { - repl_str = Z_STR_P(repl); } - result = zend_string_safe_alloc(1, Z_STRLEN_P(str) - l + ZSTR_LEN(repl_str), 0, 0); + result = zend_string_safe_alloc(1, ZSTR_LEN(str) - l + ZSTR_LEN(repl_str), 0, 0); - memcpy(ZSTR_VAL(result), Z_STRVAL_P(str), f); + memcpy(ZSTR_VAL(result), ZSTR_VAL(str), f); if (ZSTR_LEN(repl_str)) { memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(repl_str), ZSTR_LEN(repl_str)); } - memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), Z_STRVAL_P(str) + f + l, Z_STRLEN_P(str) - f - l); + memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), ZSTR_VAL(str) + f + l, ZSTR_LEN(str) - f - l); ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; zend_tmp_string_release(tmp_repl_str); RETURN_NEW_STR(result); } else { php_error_docref(NULL, E_WARNING, "Functionality of 'start' and 'length' as arrays is not implemented"); - RETURN_STR_COPY(Z_STR_P(str)); + RETURN_STR_COPY(str); } } else { /* str is array of strings */ zend_string *str_index = NULL; @@ -2393,7 +2384,7 @@ PHP_FUNCTION(substr_replace) from_idx = len_idx = repl_idx = 0; - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(str), num_index, str_index, tmp_str) { + ZEND_HASH_FOREACH_KEY_VAL(str_ht, num_index, str_index, tmp_str) { zend_string *tmp_orig_str; zend_string *orig_str = zval_get_tmp_string(tmp_str, &tmp_orig_str); @@ -2465,15 +2456,15 @@ PHP_FUNCTION(substr_replace) result_len = ZSTR_LEN(orig_str) - l; - if (Z_TYPE_P(repl) == IS_ARRAY) { - while (repl_idx < Z_ARRVAL_P(repl)->nNumUsed) { - tmp_repl = &Z_ARRVAL_P(repl)->arData[repl_idx].val; - if (Z_TYPE_P(tmp_repl) != IS_UNDEF) { + if (repl_ht) { + while (repl_idx < repl_ht->nNumUsed) { + tmp_repl = &repl_ht->arData[repl_idx].val; + if (repl_ht != IS_UNDEF) { break; } repl_idx++; } - if (repl_idx < Z_ARRVAL_P(repl)->nNumUsed) { + if (repl_idx < repl_ht->nNumUsed) { zend_string *tmp_repl_str; zend_string *repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str); @@ -2492,13 +2483,13 @@ PHP_FUNCTION(substr_replace) memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l); } } else { - result_len += Z_STRLEN_P(repl); + result_len += ZSTR_LEN(repl_str); result = zend_string_safe_alloc(1, result_len, 0, 0); memcpy(ZSTR_VAL(result), ZSTR_VAL(orig_str), f); - memcpy((ZSTR_VAL(result) + f), Z_STRVAL_P(repl), Z_STRLEN_P(repl)); - memcpy((ZSTR_VAL(result) + f + Z_STRLEN_P(repl)), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l); + memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(repl_str), ZSTR_LEN(repl_str)); + memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l); } ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; @@ -4150,25 +4141,20 @@ PHPAPI void php_stripslashes(zend_string *str) /* {{{ php_str_replace_in_subject */ -static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *subject, zval *result, int case_sensitivity) +static zend_long php_str_replace_in_subject(zval *search, zval *replace, zend_string *subject_str, zval *result, int case_sensitivity) { zval *search_entry, *replace_entry = NULL; zend_string *tmp_result, - *tmp_subject_str, *tmp_replace_entry_str = NULL, *replace_entry_str; char *replace_value = NULL; size_t replace_len = 0; zend_long replace_count = 0; - zend_string *subject_str; zend_string *lc_subject_str = NULL; uint32_t replace_idx; - /* Make sure we're dealing with strings. */ - subject_str = zval_get_tmp_string(subject, &tmp_subject_str); if (ZSTR_LEN(subject_str) == 0) { - zend_tmp_string_release(tmp_subject_str); ZVAL_EMPTY_STRING(result); return 0; } @@ -4272,7 +4258,6 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *s if (lc_subject_str) { zend_string_release_ex(lc_subject_str, 0); } - zend_tmp_string_release(tmp_subject_str); return replace_count; } } @@ -4307,7 +4292,6 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *s ZVAL_STR_COPY(result, subject_str); } } - zend_tmp_string_release(tmp_subject_str); return replace_count; } /* }}} */ @@ -4316,7 +4300,9 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zval *s */ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity) { - zval *subject, *search, *replace, *subject_entry, *zcount = NULL; + zend_string *subject_str; + HashTable *subject_ht; + zval *search, *replace, *subject_entry, *zcount = NULL; zval result; zend_string *string_key; zend_ulong num_key; @@ -4326,7 +4312,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_ZVAL(search) Z_PARAM_ZVAL(replace) - Z_PARAM_ZVAL(subject) + Z_PARAM_STR_OR_ARRAY_HT(subject_str, subject_ht) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(zcount) ZEND_PARSE_PARAMETERS_END(); @@ -4346,15 +4332,18 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit } /* if subject is an array */ - if (Z_TYPE_P(subject) == IS_ARRAY) { + if (subject_ht) { array_init(return_value); /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) { + ZEND_HASH_FOREACH_KEY_VAL(subject_ht, num_key, string_key, subject_entry) { ZVAL_DEREF(subject_entry); if (Z_TYPE_P(subject_entry) != IS_ARRAY && Z_TYPE_P(subject_entry) != IS_OBJECT) { - count += php_str_replace_in_subject(search, replace, subject_entry, &result, case_sensitivity); + zend_string *tmp_subject_str; + subject_str = zval_get_tmp_string(subject_entry, &tmp_subject_str); + count += php_str_replace_in_subject(search, replace, subject_str, &result, case_sensitivity); + zend_tmp_string_release(tmp_subject_str); } else { ZVAL_COPY(&result, subject_entry); } @@ -4366,7 +4355,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit } } ZEND_HASH_FOREACH_END(); } else { /* if subject is not an array */ - count = php_str_replace_in_subject(search, replace, subject, return_value, case_sensitivity); + count = php_str_replace_in_subject(search, replace, subject_str, return_value, case_sensitivity); } if (argc > 3) { ZEND_TRY_ASSIGN_REF_LONG(zcount, count); diff --git a/ext/standard/tests/strings/str_replace.phpt b/ext/standard/tests/strings/str_replace.phpt deleted file mode 100644 index b0ca488f3c..0000000000 --- a/ext/standard/tests/strings/str_replace.phpt +++ /dev/null @@ -1,932 +0,0 @@ ---TEST-- -Test str_replace() function ---INI-- -precision=14 ---FILE-- - --\n"; - var_dump( str_replace($search_str[$i], "FOUND", $subject, $count) ); - echo "-- search string has found '$count' times\n"; -} - - -echo "\n*** Testing Miscelleneous input data ***\n"; -/* If replace has fewer values than search, then an empty - string is used for the rest of replacement values */ -var_dump( str_replace(array("a", "a", "b"), - array("q", "q"), - "aaabb", $count - ) - ); -var_dump($count); -var_dump( str_replace(array("a", "a", "b"), - array("q", "q"), - array("aaa", "bbb", "ccc"), - $count - ) - ); -var_dump($count); - - -echo "\n-- Testing objects --\n"; -/* we get "Recoverable fatal error: saying Object of class could not be converted - to string" by default, when an object is passed instead of string: -The error can be avoided by choosing the __toString magix method as follows: */ - -class subject -{ - function __toString() { - return "Hello, world"; - } -} -$obj_subject = new subject; - -class search -{ - function __toString() { - return "Hello, world"; - } -} -$obj_search = new search; - -class replace -{ - function __toString() { - return "Hello, world"; - } -} -$obj_replace = new replace; - -var_dump(str_replace("$obj_search", "$obj_replace", "$obj_subject", $count)); -var_dump($count); - - -echo "\n-- Testing arrays --\n"; -var_dump(str_replace(array("a", "a", "b"), "multi", "aaa", $count)); -var_dump($count); - -var_dump(str_replace( array("a", "a", "b"), - array("q", "q", "c"), - "aaa", $count - ) -); -var_dump($count); - -var_dump(str_replace( array("a", "a", "b"), - array("q", "q", "c"), - array("aaa", "bbb"), - $count - ) -); -var_dump($count); - -var_dump(str_replace("a", array("q", "q", "c"), array("aaa", "bbb"), $count)); -var_dump($count); - -var_dump(str_replace("a", 1, array("aaa", "bbb"), $count)); -var_dump($count); - -var_dump(str_replace(1, 3, array("aaa1", "2bbb"), $count)); -var_dump($count); - - -echo "\n-- Testing Resources --\n"; -$resource1 = fopen( __FILE__, "r" ); -$resource2 = opendir( "." ); -var_dump(str_replace("stream", "FOUND", $resource1, $count)); -var_dump($count); -var_dump(str_replace("stream", "FOUND", $resource2, $count)); -var_dump($count); - - -echo "\n-- Testing a longer and heredoc string --\n"; -$string = << ---EXPECTF-- -*** Testing str_replace() on basic operations *** -string(0) "" -string(4) "tbst" -string(0) "" -int(0) -string(1) "q" -int(1) -string(0) "" -int(0) -string(%d) "Resource id #%d" -int(1) - -*** Testing str_replace() with various search values *** --- Iteration 0 -- -array(12) { - [0]=> - string(5) "FOUND" - [1]=> - string(0) "" - [2]=> - string(5) "FOUND" - [3]=> - string(1) "0" - [4]=> - string(6) "-FOUND" - [5]=> - string(5) "FOUND" - [6]=> - string(1) "0" - [7]=> - string(6) "-FOUND" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(5) - --- Iteration 1 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(0) - --- Iteration 2 -- -array(12) { - [0]=> - string(5) "FOUND" - [1]=> - string(0) "" - [2]=> - string(5) "FOUND" - [3]=> - string(1) "0" - [4]=> - string(6) "-FOUND" - [5]=> - string(5) "FOUND" - [6]=> - string(1) "0" - [7]=> - string(6) "-FOUND" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(5) - --- Iteration 3 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(5) "FOUND" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(5) "FOUND" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(2) - --- Iteration 4 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(5) "FOUND" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(5) "FOUND" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(2) - --- Iteration 5 -- -array(12) { - [0]=> - string(5) "FOUND" - [1]=> - string(0) "" - [2]=> - string(5) "FOUND" - [3]=> - string(1) "0" - [4]=> - string(6) "-FOUND" - [5]=> - string(5) "FOUND" - [6]=> - string(1) "0" - [7]=> - string(6) "-FOUND" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(5) - --- Iteration 6 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(5) "FOUND" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(5) "FOUND" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(2) - --- Iteration 7 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(5) "FOUND" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(5) "FOUND" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(2) - --- Iteration 8 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(0) - --- Iteration 9 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(0) - --- Iteration 10 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(5) "FOUND" - [11]=> - string(0) "" -} -int(1) - --- Iteration 11 -- -array(12) { - [0]=> - string(1) "1" - [1]=> - string(0) "" - [2]=> - string(1) "1" - [3]=> - string(1) "0" - [4]=> - string(2) "-1" - [5]=> - string(1) "1" - [6]=> - string(1) "0" - [7]=> - string(2) "-1" - [8]=> - string(0) "" - [9]=> - array(0) { - } - [10]=> - string(3) "php" - [11]=> - string(0) "" -} -int(0) - -*** Testing str_replace() with various subjects *** ---- Iteration 0 --- --- String after replacing the search value is => -- -string(177) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '2' times - ---- Iteration 1 --- --- String after replacing the search value is => -- -string(177) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '2' times - ---- Iteration 2 --- --- String after replacing the search value is => -- -string(182) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: FOUND - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 3 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 4 --- --- String after replacing the search value is => -- -string(182) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $FOUND: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 5 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 6 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 7 --- --- String after replacing the search value is => -- -string(189) "Hello, world,0120333.3445FOUND67 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 8 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 9 --- --- String after replacing the search value is => -- -string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDFOUND \xXYZ FOUND $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '2' times - ---- Iteration 10 --- --- String after replacing the search value is => -- -string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xFOUND abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 11 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 12 --- --- String after replacing the search value is => -- -string(192) "Hello, world,0120333.3445-1.234567 FOUND TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 13 --- --- String after replacing the search value is => -- -string(207) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE - FOUND«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times - ---- Iteration 14 --- --- String after replacing the search value is => -- -string(207) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE - FOUND«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times - ---- Iteration 15 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 16 --- --- String after replacing the search value is => -- -string(307) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE -FOUND FOUNDFOUNDFOUNDFOUND0«CDabcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorldFOUND - FOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '29' times - ---- Iteration 17 --- --- String after replacing the search value is => -- -string(203) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSEFOUND - FOUND0«CDFOUNDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '3' times - ---- Iteration 18 --- --- String after replacing the search value is => -- -string(194) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - FOUND«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 19 --- --- String after replacing the search value is => -- -string(194) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0FOUNDDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 20 --- --- String after replacing the search value is => -- -string(194) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - FOUND«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 21 --- --- String after replacing the search value is => -- -string(194) "Hello, world,0120333FOUND445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 22 --- --- String after replacing the search value is => -- -string(203) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" --- search string has found '3' times - ---- Iteration 23 --- --- String after replacing the search value is => -- -string(192) "Hello, world,0120333.3445-1.234567 NULL FOUND FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 24 --- --- String after replacing the search value is => -- -string(203) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" --- search string has found '3' times - ---- Iteration 25 --- --- String after replacing the search value is => -- -string(203) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" --- search string has found '3' times - ---- Iteration 26 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 27 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FOUND - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 28 --- --- String after replacing the search value is => -- -string(307) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE -FOUND FOUNDFOUNDFOUNDFOUND0«CDabcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorldFOUND - FOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '29' times - ---- Iteration 29 --- --- String after replacing the search value is => -- -string(186) "Hello, world,0120333.3445-1.234567FOUNDNULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '1' times - ---- Iteration 30 --- --- String after replacing the search value is => -- -string(199) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDaFOUNDcd \xXYZ aFOUNDcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '2' times - ---- Iteration 31 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 32 --- --- String after replacing the search value is => -- -string(203) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - FOUND 0«CDabcd \xXYZFOUNDabcd $$@#%^&*!~,.:;?: !!Hello, World -FOUND ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '3' times - ---- Iteration 33 --- --- String after replacing the search value is => -- -string(191) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE - 0«CDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '0' times - ---- Iteration 34 --- --- String after replacing the search value is => -- -string(5) "FOUND" --- search string has found '1' times - -*** Testing Miscelleneous input data *** -string(3) "qqq" -int(5) -array(3) { - [0]=> - string(3) "qqq" - [1]=> - string(0) "" - [2]=> - string(3) "ccc" -} -int(6) - --- Testing objects -- -string(12) "Hello, world" -int(1) - --- Testing arrays -- -string(15) "multimultimulti" -int(3) -string(3) "qqq" -int(3) -array(2) { - [0]=> - string(3) "qqq" - [1]=> - string(3) "ccc" -} -int(6) - -Warning: Array to string conversion in %s on line %d -array(2) { - [0]=> - string(15) "ArrayArrayArray" - [1]=> - string(3) "bbb" -} -int(3) -array(2) { - [0]=> - string(3) "111" - [1]=> - string(3) "bbb" -} -int(3) -array(2) { - [0]=> - string(4) "aaa3" - [1]=> - string(4) "2bbb" -} -int(1) - --- Testing Resources -- -string(%d) "Resource id #%d" -int(0) -string(%d) "Resource id #%d" -int(0) - --- Testing a longer and heredoc string -- -string(623) "FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -@#$%^&**&^%$#@!~:())))((((&&&**%$###@@@!!!~~~~@###$%^&* -FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789" -int(16) - --- Testing a heredoc null string -- -string(0) "" -int(0) - --- Testing simple and complex syntax strings -- -string(5) "FOUND" -string(5) "FOUND" - -Warning: Undefined variable: strS in %s on line %d -string(0) "" -string(5) "FOUND" -string(5) "FOUND" -Done diff --git a/ext/standard/tests/strings/str_replace_basic.phpt b/ext/standard/tests/strings/str_replace_basic.phpt index 22b674ea6f..fa39b24e3a 100644 --- a/ext/standard/tests/strings/str_replace_basic.phpt +++ b/ext/standard/tests/strings/str_replace_basic.phpt @@ -28,7 +28,11 @@ var_dump( $count ); $fp = fopen( __FILE__, "r" ); $fp_copy = $fp; -var_dump( str_replace($fp_copy, $fp_copy, $fp_copy, $fp_copy) ); +try { + var_dump( str_replace($fp_copy, $fp_copy, $fp_copy, $fp_copy) ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} var_dump( $fp_copy ); fclose($fp); @@ -43,5 +47,5 @@ string(1) "q" int(1) string(0) "" int(0) -string(%d) "Resource id #%d" -int(1) +str_replace() expects parameter 3 to be string or array, resource given +resource(%d) of type (stream) diff --git a/ext/standard/tests/strings/str_replace_variation3.phpt b/ext/standard/tests/strings/str_replace_variation3.phpt index 7c520b404d..040e37970d 100644 --- a/ext/standard/tests/strings/str_replace_variation3.phpt +++ b/ext/standard/tests/strings/str_replace_variation3.phpt @@ -95,10 +95,16 @@ var_dump($count); echo "\n-- Testing Resources --\n"; $resource1 = fopen( __FILE__, "r" ); $resource2 = opendir( "." ); -var_dump(str_replace("stream", "FOUND", $resource1, $count)); -var_dump($count); -var_dump(str_replace("stream", "FOUND", $resource2, $count)); -var_dump($count); +try { + var_dump(str_replace("stream", "FOUND", $resource1, $count)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(str_replace("stream", "FOUND", $resource2, $count)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} echo "\n-- Testing a longer and heredoc string --\n"; @@ -194,10 +200,8 @@ array(2) { int(1) -- Testing Resources -- -string(%d) "Resource id #%d" -int(0) -string(%d) "Resource id #%d" -int(0) +str_replace() expects parameter 3 to be string or array, resource given +str_replace() expects parameter 3 to be string or array, resource given -- Testing a longer and heredoc string -- string(623) "FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 -- 2.50.1