public static function safeSubstr(string $str, int $start = 0, $length = null) : string
{
static $exists = null;
if ($exists === null) {
$exists = \is_callable('\\mb_substr');
}
if ($exists) {
// mb_substr($str, 0, NULL, '8bit') returns an empty string on PHP
// 5.3, so we have to find the length ourselves.
if ($length === null) {
if ($start >= 0) {
$length = self::safeStrlen($str) - $start;
} else {
$length = -$start;
}
} elseif (!\is_int($length)) {
throw new InvalidType('Argument 3: integer expected');
}
// $length calculation above might result in a 0-length string
if ($length === 0 || $start > self::safeStrlen($str)) {
return '';
}
return \mb_substr($str, $start, $length, '8bit');
}
if ($length === 0) {
return '';
}
// Unlike mb_substr(), substr() doesn't accept NULL for length
if ($length !== null) {
return \substr($str, $start, $length);
} else {
return \substr($str, $start);
}
}