Add cyclic string replacements
- Version: 1.7
- Creation date: 2015-01-05
- Last modification date : 2015-04-02
- Author: François Laupretre, firstname.lastname@example.org
- Status: Abandoned
- First Published at: http://wiki.php.net/rfc/cyclic-replace
This RFC improves the str_replace() and str_ireplace() functions.
The additional feature is named 'cyclic replace' in the rest of the document.
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 / 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, it loops to the first element, and so on.
Note that replacements are done in array order. Key values are ignored in replace arrays.
So, features brought by this RFC to str_[i]replace() are :
When search is a string and replace an array, cyclic replace is performed. This is the 'first-level' case.
When search and replace are arrays, each element of the replace array can 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 around the 'string search' case, providing exactly the same features.
Other feature : Arbitrarily nested subject arrays are now supported, returning exactly the same array structure and preserving keys. Only values are replaced.
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. If search is an array, this warning can be raised more than once during a single str_[i]replace() execution, as we raise it each time we meet an empty replace array.
Backward Incompatible Changes
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.
Different behavior too each time we meet an empty array as replace value. Previously, as seen above, an E_NOTICE was raised and the array was converted to 'Array'. Now, an E_WARNING is raised and the subject is returned unchanged.
The support of arbitrarily-nested subject brings the same kind of BC because previous implementations supported one array level only.
All these BC breaks are similar and deal with array to string conversions in previous implementations. These can be considered as very low impact because relying on an array-to-string conversion (with E_NOTICE) when calling these functions, while theoritically supported, is very improbable.
Proposed PHP Version(s)
To Existing Extensions
Adds the php_str_to_array() and php_str_to_array_ex() functions. These functions perform cyclic replacements on an input string.
Unaffected PHP Functionality
- Add (search=null, replace=array) syntax. Would take search from array_keys(replace). An array of (search ⇒ replace) elements would be, IMO, a more intuitive way to specify multiple replacements.
- Add similar features (cyclic replacement and multi-level array recursion) to preg_replace() and preg_filter().
Proposed Voting Choices
Required majority : 50%+1.
Patches and Tests
Pull request against PHP7 branch (work in progress) : https://github.com/php/php-src/pull/980
After the project is implemented, this section should contain
- the version(s) it was merged to
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
Feature Requests :
Pull Request :
Support for arbitrarily-nested search/replace arrays is abandoned. Additional 'options' argument to str_replace() is abandoned.