Last active
October 4, 2017 19:21
-
-
Save antichris/1dd951752f3da125d382420be21d5b16 to your computer and use it in GitHub Desktop.
An `mb_substr_replace()` implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Replace text within a portion of a multi-byte string | |
* <p> | |
* Performs a multi-byte safe <i>{@link substr_replace()}</i> operation replacing a copy of <i>string</i> delimited by | |
* the <i>start</i> and (optionally) <i>length</i> parameters with the string given in <i>replacement</i>. | |
* | |
* @see http://php.net/manual/en/function.substr-replace.php | |
* @see http://php.net/manual/en/function.mb-substr.php | |
* | |
* @param mixed $string The input string. | |
* <p> | |
* An array of strings can be provided, in which case the replacements will occur on each string in turn. In this case, | |
* the <i>replacement</i>, <i>start</i>, <i>length</i> and <i>encoding</i> parameters may be provided either as scalar | |
* values to be applied to each input string in turn, or as arrays, in which case the corresponding array element will | |
* be used for each input string. | |
* | |
* @param mixed $replacement The replacement string. | |
* | |
* @param mixed $start If <i>start</i> is positive, the replacing will begin at the <i>start</i>'th offset into | |
* <i>string</i>. | |
* <p> | |
* If <i>start</i> is negative, the replacing will begin at the <i>start</i>'th character from the end of <i>string</i>. | |
* | |
* @param mixed $length [optional] | |
* <p> | |
* If given and is positive, it represents the length of the portion of <i>string</i> which is to be replaced. If it is | |
* negative, it represents the number of characters from the end of <i>string</i> at which to stop replacing. If it is | |
* not given or equals to <b>NULL</b> or an empty string, then it will default to strlen( <i>string</i> ); i.e. end the | |
* replacing at the end of <i>string</i>. If <i>length</i> is zero then this function will have the effect of inserting | |
* <i>replacement</i> into <i>string</i> at the given <i>start</i> offset. | |
* | |
* @param mixed $encoding [optional] | |
* <p> | |
* The <i>encoding</i> parameter is the character encoding. If it is omitted, the internal character encoding value will | |
* be used. | |
* | |
* @return mixed The result string is returned. If <i>string</i> is an array then array is returned. | |
*/ | |
function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null) | |
{ | |
if (!$encoding) { | |
$encoding = mb_internal_encoding(); | |
} | |
if (is_array($string)) { | |
$stringCount = count($string); | |
if (is_array($replacement)) { | |
if (count($replacement) < $stringCount) { | |
$replacement = array_pad($replacement, $stringCount, ''); | |
} | |
} else { | |
$replacement = array_fill(0, $stringCount, $replacement); | |
} | |
if (is_array($start)) { | |
if (count($start) < $stringCount) { | |
$start = array_pad($start, $stringCount, 0); | |
} | |
} else { | |
$start = array_fill(0, $stringCount, $start); | |
} | |
if (is_array($length)) { | |
if (count($length) < $stringCount) { | |
$length = array_pad($length, $stringCount, null); | |
} | |
} else { | |
$length = array_fill(0, $stringCount, $length); | |
} | |
if (is_array($encoding)) { | |
if (count($encoding) < $stringCount) { | |
$encoding = array_pad($encoding, $stringCount, mb_internal_encoding()); | |
} | |
} else { | |
$encoding = array_fill(0, $stringCount, $encoding); | |
} | |
return array_map(__METHOD__, $string, $replacement, $start, $length, $encoding); | |
} | |
$stringLength = mb_strlen($string, $encoding); | |
if ($start < 0) { | |
if (-$start < $stringLength) { | |
$startNormalized = $stringLength + $start; | |
} else { | |
$startNormalized = 0; | |
} | |
} else if ($start > $stringLength) { | |
$startNormalized = $stringLength; | |
} else { | |
$startNormalized = $start; | |
} | |
if ($length === null || $length === '') { | |
$start2 = $stringLength; | |
} else if ($length < 0) { | |
$start2 = $stringLength + $length; | |
if ($start2 < $startNormalized) { | |
$start2 = $startNormalized; | |
} | |
} else { | |
$start2 = $startNormalized + $length; | |
} | |
$leader = $startNormalized | |
? mb_substr($string, 0, $startNormalized, $encoding) | |
: ''; | |
$trailer = $start2 < $stringLength | |
? mb_substr($string, $start2, null, $encoding) | |
: ''; | |
return "{$leader}{$replacement}{$trailer}"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment