summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Dai <demon@php.net>2015-03-13 11:52:36 +0800
committerWei Dai <demon@php.net>2015-03-13 11:52:36 +0800
commit25566c67fef76e01a25816b95e68a73a7cc2b64e (patch)
tree177e8c2827f453e93f5e4c8fa93b201048cbf769
parent61406a527f42a960e248e01070bb90419a71f2df (diff)
downloadphp-git-25566c67fef76e01a25816b95e68a73a7cc2b64e.tar.gz
Implement preg_replace_callback_array function
-rw-r--r--Zend/zend_vm_gen.php81
-rw-r--r--ext/pcre/php_pcre.c164
-rw-r--r--ext/pcre/tests/preg_replace_callback_array.phpt39
-rw-r--r--ext/pcre/tests/preg_replace_callback_array2.phpt40
-rw-r--r--ext/pcre/tests/preg_replace_callback_array3.phpt39
-rw-r--r--ext/pcre/tests/preg_replace_callback_array4.phpt40
-rw-r--r--sapi/cli/tests/006.phpt9
7 files changed, 335 insertions, 77 deletions
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 65b1c72c06..de66357363 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -519,67 +519,56 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
// Updating code according to selected threading model
switch($kind) {
case ZEND_VM_KIND_CALL:
- $code = preg_replace_callback(
+ $code = preg_replace_callback_array(
array(
- "/EXECUTE_DATA/m",
- "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/m",
- ),
- function($matches) use ($spec, $prefix, $op1, $op2) {
- if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
- return "execute_data";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ "/EXECUTE_DATA/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
+ return "execute_data";
+ },
+ "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "return " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
- return "return " . helper_name($matches[1], $spec, $op1, $op2) . "(" . $matches[2]. ", ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);";
- } else {
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "return " . helper_name($matches[1], $spec, $op1, $op2) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)";
- }
- },
- $code);
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
+ return "return " . helper_name($matches[1], $spec, $op1, $op2) . "(" . $matches[2]. ", ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);";
+ },
+ ), $code);
break;
case ZEND_VM_KIND_SWITCH:
- $code = preg_replace_callback(
+ $code = preg_replace_callback_array(
array(
- "/EXECUTE_DATA/m",
- "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
- ),
- function($matches) use ($spec, $prefix, $op1, $op2) {
- if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+ "/EXECUTE_DATA/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "execute_data";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ },
+ "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_LABEL";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
- return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
- } else {
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "goto " . helper_name($matches[1], $spec, $op1, $op2);
- }
- },
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
+ return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
+ },
+ ),
$code);
break;
case ZEND_VM_KIND_GOTO:
- $code = preg_replace_callback(
+ $code = preg_replace_callback_array(
array(
- "/EXECUTE_DATA/m",
- "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
- ),
- function($matches) use ($spec, $prefix, $op1, $op2) {
- if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
- return "execute_data";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ "/EXECUTE_DATA/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
+ return "execute_data";
+ },
+ "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER";
- } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
- return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
- } else {
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
return "goto " . helper_name($matches[1], $spec, $op1, $op2);
- }
- },
- $code);
+ },
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m" => function($matches) use ($spec, $prefix, $op1, $op2) {
+ return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
+ },
+ ), $code);
break;
}
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 27440bb490..5f579e0004 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -1353,37 +1353,16 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub
/* {{{ preg_replace_impl
*/
-static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_replace, int is_filter)
+static void preg_replace_impl(zval *return_value, int argc, zval *regex, zval *replace, zval *subject, zend_long limit, zval *zcount, int is_callable_replace, int is_filter)
{
- zval *regex,
- *replace,
- *subject,
- *subject_entry,
- *zcount = NULL;
+ zval *subject_entry;
int limit_val = -1;
- zend_long limit = -1;
zend_string *result;
zend_string *string_key;
zend_ulong num_key;
zend_string *callback_name;
int replace_count=0, old_replace_count;
-#ifndef FAST_ZPP
- /* Get function parameters and do error-checking. */
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|lz/", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
- return;
- }
-#else
- ZEND_PARSE_PARAMETERS_START(3, 5)
- Z_PARAM_ZVAL(regex)
- Z_PARAM_ZVAL(replace)
- Z_PARAM_ZVAL(subject)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(limit)
- Z_PARAM_ZVAL_EX(zcount, 0, 1)
- ZEND_PARSE_PARAMETERS_END();
-#endif
-
if (!is_callable_replace && Z_TYPE_P(replace) == IS_ARRAY && Z_TYPE_P(regex) != IS_ARRAY) {
php_error_docref(NULL, E_WARNING, "Parameter mismatch, pattern is a string while replacement is an array");
RETURN_FALSE;
@@ -1403,7 +1382,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
zend_string_release(callback_name);
}
- if (ZEND_NUM_ARGS() > 3) {
+ if (argc > 3) {
limit_val = (int)limit;
}
@@ -1433,7 +1412,8 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
}
}
} ZEND_HASH_FOREACH_END();
- } else { /* if subject is not an array */
+ } else {
+ /* if subject is not an array */
old_replace_count = replace_count;
if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count)) != NULL) {
if (!is_filter || replace_count > old_replace_count) {
@@ -1443,11 +1423,10 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
}
}
}
- if (ZEND_NUM_ARGS() > 4) {
+ if (argc > 4) {
zval_dtor(zcount);
ZVAL_LONG(zcount, replace_count);
}
-
}
/* }}} */
@@ -1455,7 +1434,26 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
Perform Perl-style regular expression replacement. */
static PHP_FUNCTION(preg_replace)
{
- preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
+ zval *regex, *replace, *subject, *zcount = NULL;
+ zend_long limit = -1;
+
+#ifndef FAST_ZPP
+ /* Get function parameters and do error-checking. */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|lz/", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
+ return;
+ }
+#else
+ ZEND_PARSE_PARAMETERS_START(3, 5)
+ Z_PARAM_ZVAL(regex)
+ Z_PARAM_ZVAL(replace)
+ Z_PARAM_ZVAL(subject)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(limit)
+ Z_PARAM_ZVAL_EX(zcount, 0, 1)
+ ZEND_PARSE_PARAMETERS_END();
+#endif
+
+ preg_replace_impl(return_value, ZEND_NUM_ARGS(), regex, replace, subject, limit, zcount, 0, 0);
}
/* }}} */
@@ -1463,7 +1461,84 @@ static PHP_FUNCTION(preg_replace)
Perform Perl-style regular expression replacement using replacement callback. */
static PHP_FUNCTION(preg_replace_callback)
{
- preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
+ zval *regex, *replace, *subject, *zcount = NULL;
+ zend_long limit = -1;
+
+#ifndef FAST_ZPP
+ /* Get function parameters and do error-checking. */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|lz/", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
+ return;
+ }
+#else
+ ZEND_PARSE_PARAMETERS_START(3, 5)
+ Z_PARAM_ZVAL(regex)
+ Z_PARAM_ZVAL(replace)
+ Z_PARAM_ZVAL(subject)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(limit)
+ Z_PARAM_ZVAL_EX(zcount, 0, 1)
+ ZEND_PARSE_PARAMETERS_END();
+#endif
+
+ preg_replace_impl(return_value, ZEND_NUM_ARGS(), regex, replace, subject, limit, zcount, 1, 0);
+}
+/* }}} */
+
+/* {{{ proto mixed preg_replace_callback_array(array pattern, mixed subject [, int limit [, int &count]])
+ Perform Perl-style regular expression replacement using replacement callback. */
+static PHP_FUNCTION(preg_replace_callback_array)
+{
+ zval regex, tmp_ret, *replace, *subject, *pattern, *zcount = NULL;
+ zend_long limit = -1;
+ zend_ulong num_idx, count = 0;
+ zend_string *str_idx;
+ int argc;
+
+#ifndef FAST_ZPP
+ /* Get function parameters and do error-checking. */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "az|lz/", &pattern, &subject, &limit, &zcount) == FAILURE) {
+ return;
+ }
+#else
+ ZEND_PARSE_PARAMETERS_START(2, 4)
+ Z_PARAM_ARRAY(pattern)
+ Z_PARAM_ZVAL(subject)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(limit)
+ Z_PARAM_ZVAL_EX(zcount, 0, 1)
+ ZEND_PARSE_PARAMETERS_END();
+#endif
+ argc = ZEND_NUM_ARGS();
+
+ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(pattern), num_idx, str_idx, replace) {
+ if (str_idx) {
+ ZVAL_STR_COPY(&regex, str_idx);
+ } else {
+ php_error_docref(NULL, E_WARNING, "Delimiter must not be alphanumeric or backslash");
+ zval_dtor(return_value);
+ ZVAL_COPY(return_value, subject);
+ break;
+ }
+
+ if (Z_ISNULL_P(return_value)) {
+ preg_replace_impl(&tmp_ret, argc + 1, &regex, replace, subject, limit, zcount, 1, 0);
+ } else {
+ preg_replace_impl(&tmp_ret, argc + 1, &regex, replace, return_value, limit, zcount, 1, 0);
+ zval_ptr_dtor(return_value);
+ }
+
+ if (zcount && Z_TYPE_P(zcount) == IS_LONG) {
+ count += Z_LVAL_P(zcount);
+ }
+
+ ZVAL_COPY_VALUE(return_value, &tmp_ret);
+ zval_ptr_dtor(&regex);
+ } ZEND_HASH_FOREACH_END();
+
+ if (zcount && Z_TYPE_P(zcount) == IS_LONG) {
+ zval_dtor(zcount);
+ ZVAL_LONG(zcount, count);
+ }
}
/* }}} */
@@ -1471,7 +1546,26 @@ static PHP_FUNCTION(preg_replace_callback)
Perform Perl-style regular expression replacement and only return matches. */
static PHP_FUNCTION(preg_filter)
{
- preg_replace_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
+ zval *regex, *replace, *subject, *zcount = NULL;
+ zend_long limit = -1;
+
+#ifndef FAST_ZPP
+ /* Get function parameters and do error-checking. */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|lz/", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
+ return;
+ }
+#else
+ ZEND_PARSE_PARAMETERS_START(3, 5)
+ Z_PARAM_ZVAL(regex)
+ Z_PARAM_ZVAL(replace)
+ Z_PARAM_ZVAL(subject)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_LONG(limit)
+ Z_PARAM_ZVAL_EX(zcount, 0, 1)
+ ZEND_PARSE_PARAMETERS_END();
+#endif
+
+ preg_replace_impl(return_value, ZEND_NUM_ARGS(), regex, replace, subject, limit, zcount, 0, 1);
}
/* }}} */
@@ -1780,7 +1874,7 @@ static PHP_FUNCTION(preg_quote)
/* Reallocate string and return it */
out_str = zend_string_realloc(out_str, q - out_str->val, 0);
- RETURN_STR(out_str);
+ RETURN_NEW_STR(out_str);
}
/* }}} */
@@ -1953,6 +2047,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace_callback, 0, 0, 3)
ZEND_ARG_INFO(1, count)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace_callback_array, 0, 0, 2)
+ ZEND_ARG_INFO(0, pattern)
+ ZEND_ARG_INFO(0, subject)
+ ZEND_ARG_INFO(0, limit)
+ ZEND_ARG_INFO(1, count)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_split, 0, 0, 2)
ZEND_ARG_INFO(0, pattern)
ZEND_ARG_INFO(0, subject)
@@ -1980,6 +2081,7 @@ static const zend_function_entry pcre_functions[] = {
PHP_FE(preg_match_all, arginfo_preg_match_all)
PHP_FE(preg_replace, arginfo_preg_replace)
PHP_FE(preg_replace_callback, arginfo_preg_replace_callback)
+ PHP_FE(preg_replace_callback_array, arginfo_preg_replace_callback_array)
PHP_FE(preg_filter, arginfo_preg_replace)
PHP_FE(preg_split, arginfo_preg_split)
PHP_FE(preg_quote, arginfo_preg_quote)
diff --git a/ext/pcre/tests/preg_replace_callback_array.phpt b/ext/pcre/tests/preg_replace_callback_array.phpt
new file mode 100644
index 0000000000..04ee8465ea
--- /dev/null
+++ b/ext/pcre/tests/preg_replace_callback_array.phpt
@@ -0,0 +1,39 @@
+--TEST--
+preg_replace_callback_array()
+--FILE--
+<?php
+
+function f() {
+ throw new Exception();
+}
+
+try {
+var_dump(preg_replace_callback_array(array('/\w/' => 'f'), 'z'));
+} catch(Exception $e) {}
+
+function g($x) {
+ return "'$x[0]'";
+}
+
+var_dump(preg_replace_callback_array(array('@\b\w{1,2}\b@' => 'g'), array('a b3 bcd', 'v' => 'aksfjk', 12 => 'aa bb')));
+
+var_dump(preg_replace_callback_array(array('~\A.~' => 'g'), array(array('xyz'))));
+
+var_dump(preg_replace_callback_array(array('~\A.~' => create_function('$m', 'return strtolower($m[0]);')), 'ABC'));
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ string(12) "'a' 'b3' bcd"
+ ["v"]=>
+ string(6) "aksfjk"
+ [12]=>
+ string(9) "'aa' 'bb'"
+}
+
+Notice: Array to string conversion in %spreg_replace_callback_array.php on line %d
+array(1) {
+ [0]=>
+ string(7) "'A'rray"
+}
+string(3) "aBC"
diff --git a/ext/pcre/tests/preg_replace_callback_array2.phpt b/ext/pcre/tests/preg_replace_callback_array2.phpt
new file mode 100644
index 0000000000..dc6cbde85c
--- /dev/null
+++ b/ext/pcre/tests/preg_replace_callback_array2.phpt
@@ -0,0 +1,40 @@
+--TEST--
+preg_replace_callback_array() 2
+--FILE--
+<?php
+
+var_dump(preg_replace_callback_array());
+var_dump(preg_replace_callback_array(1));
+var_dump(preg_replace_callback_array(1,2));
+var_dump(preg_replace_callback_array(1,2,3));
+$a = 5;
+var_dump(preg_replace_callback_array(1,2,3,$a));
+$a = "";
+var_dump(preg_replace_callback_array(array("" => ""),"","",$a));
+$a = array();
+var_dump(preg_replace_callback($a,$a,$a,$a));
+
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: preg_replace_callback_array() expects at least 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: preg_replace_callback_array() expects at least 2 parameters, 1 given in %s on line %d
+NULL
+
+Warning: preg_replace_callback_array() expects parameter 1 to be array, integer given in %s on line %d
+NULL
+
+Warning: preg_replace_callback_array() expects parameter 1 to be array, integer given in %s on line %d
+NULL
+
+Warning: preg_replace_callback_array() expects parameter 1 to be array, integer given in %s on line %d
+NULL
+
+Warning: preg_replace_callback_array() expects parameter 3 to be integer, string given in %s on line %d
+NULL
+
+Warning: preg_replace_callback() expects parameter 4 to be integer, array given in %s on line %d
+NULL
+Done
diff --git a/ext/pcre/tests/preg_replace_callback_array3.phpt b/ext/pcre/tests/preg_replace_callback_array3.phpt
new file mode 100644
index 0000000000..b0834327ff
--- /dev/null
+++ b/ext/pcre/tests/preg_replace_callback_array3.phpt
@@ -0,0 +1,39 @@
+--TEST--
+preg_replace_callback_array() 3
+--FILE--
+<?php
+$code = "test-EXECUTE_DATA-xcvxcv-ZEND_VM_DISPATCH_TO_HELPER";
+
+$code = preg_replace_callback_array(
+ array(
+ "/EXECUTE_DATA/m" => function($matches) { return "execute_data";},
+ "/ZEND_VM_DISPATCH_TO_HANDLER/m" => function($matches) { return "handler"; },
+ "/ZEND_VM_DISPATCH_TO_HELPER/m" => function($matches) { return "helper"; },
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX/m" => function($matches) { return "helper_ex"; },
+ ),
+ $code);
+
+var_dump($code);
+$code = array("test-EXECUTE_DATA-ZEND_VM_DISPATCH_TO_HELPER_EX-test",
+ "test-sdf-xcvxcv-ZEND_VM_DISPATCH_TO_HELPER_EX-test-EXECUTE_DATA-test");
+
+$code = preg_replace_callback_array(
+ array(
+ "/EXECUTE_DATA/m" => function($matches) { return "execute_data";},
+ "/ZEND_VM_DISPATCH_TO_HANDLER/m" => function($matches) { return "handler"; },
+ "/ZEND_VM_DISPATCH_TO_HELPER/m" => function($matches) { return "helper"; },
+ ),
+ $code, -1, $count);
+
+var_dump($code, $count);
+
+?>
+--EXPECTF--
+string(31) "test-execute_data-xcvxcv-helper"
+array(2) {
+ [0]=>
+ string(32) "test-execute_data-helper_EX-test"
+ [1]=>
+ string(48) "test-sdf-xcvxcv-helper_EX-test-execute_data-test"
+}
+int(4)
diff --git a/ext/pcre/tests/preg_replace_callback_array4.phpt b/ext/pcre/tests/preg_replace_callback_array4.phpt
new file mode 100644
index 0000000000..12065ab36b
--- /dev/null
+++ b/ext/pcre/tests/preg_replace_callback_array4.phpt
@@ -0,0 +1,40 @@
+--TEST--
+preg_replace_callback_array() 4
+--FILE--
+<?php
+$code = "test-EXECUTE_DATA-xcvxcv-ZEND_VM_DISPATCH_TO_HELPER";
+
+$code = preg_replace_callback_array(
+ array(
+ "/EXECUTE_DATA/m" => function($matches) { return "execute_data";},
+ "/ZEND_VM_DISPATCH_TO_HANDLER/m" => function($matches) { return "handler"; },
+ "/ZEND_VM_DISPATCH_TO_HELPER/m" => function($matches) { return "helper"; },
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX/m" => function($matches) { return "helper_ex"; },
+ ),
+ $code);
+
+var_dump($code);
+$code = array("test-EXECUTE_DATA-ZEND_VM_DISPATCH_TO_HELPER_EX-test",
+ "test-sdf-xcvxcv-ZEND_VM_DISPATCH_TO_HELPER_EX-test-EXECUTE_DATA-test");
+
+$code = preg_replace_callback_array(
+ array(
+ "/ZEND_VM_DISPATCH_TO_HANDLER/m" => function($matches) { return "handler"; },
+ 23234 => function($matches) { return "execute_data";},
+ "/ZEND_VM_DISPATCH_TO_HELPER/m" => function($matches) { return "helper"; },
+ ),
+ $code, -1, $count);
+
+var_dump($code, $count);
+?>
+--EXPECTF--
+string(31) "test-execute_data-xcvxcv-helper"
+
+Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %s on line %d
+array(2) {
+ [0]=>
+ string(52) "test-EXECUTE_DATA-ZEND_VM_DISPATCH_TO_HELPER_EX-test"
+ [1]=>
+ string(68) "test-sdf-xcvxcv-ZEND_VM_DISPATCH_TO_HELPER_EX-test-EXECUTE_DATA-test"
+}
+int(0)
diff --git a/sapi/cli/tests/006.phpt b/sapi/cli/tests/006.phpt
index e9e8b7e219..516ccfd806 100644
--- a/sapi/cli/tests/006.phpt
+++ b/sapi/cli/tests/006.phpt
@@ -97,6 +97,15 @@ string(%d) "Extension [ <persistent> extension #%d pcre version <no_version> ] {
Parameter #4 [ <optional> &$count ]
}
}
+ Function [ <internal:pcre> preg_replace_callback_array ] {
+
+ - Parameters [4] {
+ Parameter #0 [ <required> $pattern ]
+ Parameter #1 [ <required> $subject ]
+ Parameter #2 [ <optional> $limit ]
+ Parameter #3 [ <optional> &$count ]
+ }
+ }
Function [ <internal:pcre> function preg_filter ] {
- Parameters [5] {