rfc:cyclic-replace

This is an old revision of the document!


Add cyclic string replacements

Introduction

This RFC improves the str_replace() and str_ireplace() functions.

The additional feature is named 'cyclic replace' in the rest of the document.

Proposal

The idea originated as a feature request back in 2006 (https://bugs.php.net/bug.php?id=38685) and was recently revived, refined, and improved by the internals community.

In the current str_[i]replace() implementation, the case (string search and array replace) is supported but quite useless as, in this case, the replace array is converted to the 'Array' string and, then, string/string conversion is performed.

This RFC proposes that, in this case, the first occurence of search is replaced with the first element of the replace array, the second occurence with the second element, and so on. When we arrive at the end of the replace array, several behaviors can be chosen (loop, repeat last element, etc... see the options parameter below).

This is what we name 'cyclic replace'. Purists will note that it is really 'cyclic' only when we set the option to loop in the replace array but I didn't find a better name.

Features brought by this RFC to str_[i]replace() :

  • When search is a string and replace an array, cyclic replace is performed.
  • When search and replace are arrays, each element of the replace array can now be a string or an array. If it is a string, we have the usual string/string behavior. If it is an array, cyclic replacement is performed. So, the 'array search' case is an implicit loop whose body provides exactly the same features as when search is received as a string.

Empty replace arrays are considered as unexpected. When one is provided, an E_WARNING error is raised and the input subject is returned as-is.

Backward Incompatible Changes

C API

php_char_to_str_ex() and php_str_to_str_ex() (defined in ext/standard/php_string.h) take an additional options argument. This argument is not used at the moment but, this allows their API to remain compatible with the new new php_str_to_array_ex() function.

Note that the API for php_char_to_str() and php_str_to_str() is not modified.

PHP API

In str_[i]replace() functions, search as a string and replace as an array caused the replace array to be converted to string, giving 'Array' and raising an E_NOTICE.

Now, this combination of argument types causes the search string to be replaced with elements from the replace array. So, the behavior is different.

The BC break is minimal here as I hope very few people ever relied on a replace array being converted to 'Array', especially with an E_NOTICE.

Proposed PHP Version(s)

PHP 7

RFC Impact

To SAPIs

None

To Existing Extensions

Extensions using one the C functions with a modified API need to be adapted (add a 0 argument to each call).

To Opcache

None

New Constants

C constants

These new C constants are defined in ext/standard/php_strings.h :

  • PHP_STR_ARRAY_REPLACE_STOP
  • PHP_STR_ARRAY_REPLACE_FIRST
  • PHP_STR_ARRAY_REPLACE_LAST
  • PHP_STR_ARRAY_REPLACE_LOOP
  • PHP_STR_ARRAY_REPLACE_EMPTY
  • PHP_STR_ARRAY_REPLACE_MASK

PHP constants

New constants are defined to allow controlling how the replacements are done after a replace array is exhausted (when there are more occurences of search in the subject than the number of elements in the replace array). These constants are exclusive (they cannot be combined) :

  • STR_REPLACE_STOP : Stop replacements (up to count(replace) occurences of needle can be replaced)
  • STR_REPLACE_FIRST : Remaining occurences are replaced with the first element of the replace array.
  • STR_REPLACE_LAST : Remaining occurences are replaced with the last element of the replace array.
  • STR_REPLACE_LOOP : Loop and restart replacements with the first element of the replace array. Looping occurs as many times as needed.
  • STR_REPLACE_EMPTY : Remaining occurences are replaced with an empty string.

API changes

PHP API

An additional optional argument, named options in the documentation, is added at the end of the argument list for str_replace() and str_ireplace().

If set, its value must be one of the STR_REPLACE_xxx constants defined above.

When not set, the default value is STR_REPLACE_STOP.

C API

Adds the php_str_to_array() and php_str_to_array_ex() functions. These functions perform cyclic replacements on an input string.

Open Issues

None

Unaffected PHP Functionality

The C API for php_char_to_str() and php_str_to_str() is left unchanged.

Future Scope

Propose the addition of a similar feature to preg_replace() and preg_filter().

Proposed Voting Choices

Not sure of required majority for this feature. Probably 2/3.

Patches and Tests

Pull request against current PHP7 branch : https://github.com/php/php-src/pull/980

When implementation will be complete, this PR is intended to be the final patch.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

(Keep this updated with features that were discussed on the mail lists)

rfc/cyclic-replace.1420760767.txt.gz · Last modified: 2017/09/22 13:28 (external edit)