Skip to content

Mb trim functions #469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Polyfills are provided for:
- the `mb_ucfirst` and `mb_lcfirst` functions introduced in PHP 8.4;
- the `array_find`, `array_find_key`, `array_any` and `array_all` functions introduced in PHP 8.4;
- the `Deprecated` attribute introduced in PHP 8.4;
- the `mb_trim`, `mb_ltrim` and `mb_rtrim` functions introduced in PHP 8.4;

It is strongly recommended to upgrade your PHP version and/or install the missing
extensions whenever possible. This polyfill should be used only when there is no
Expand Down
67 changes: 64 additions & 3 deletions src/Mbstring/Mbstring.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
* - mb_substr_count - Count the number of substring occurrences
* - mb_ucfirst - Make a string's first character uppercase
* - mb_lcfirst - Make a string's first character lowercase
* - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string
* - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string
* - mb_rtrim - Strip whitespace (or other characters) from the end of a string
*
* Not implemented:
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
Expand Down Expand Up @@ -83,7 +86,7 @@ final class Mbstring
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($s)) {
if (PHP_VERSION_ID < 70200) {
if (\PHP_VERSION_ID < 70200) {
trigger_error('mb_convert_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);

return null;
Expand Down Expand Up @@ -980,17 +983,75 @@ private static function getEncoding($encoding)
return $encoding;
}

public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}

public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
}

public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__);
}

private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given');
}

if ('' === $characters) {
return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
}

if ('UTF-8' === $encoding) {
$encoding = null;
if (!preg_match('//u', $string)) {
$string = @iconv('UTF-8', 'UTF-8//IGNORE', $string);
}
if (null !== $characters && !preg_match('//u', $characters)) {
$characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters);
}
} else {
$string = iconv($encoding, 'UTF-8//IGNORE', $string);

if (null !== $characters) {
$characters = iconv($encoding, 'UTF-8//IGNORE', $characters);
}
}

if (null === $characters) {
$characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}";
} else {
$characters = preg_quote($characters);
}

$string = preg_replace(sprintf($regex, $characters), '', $string);

if (null === $encoding) {
return $string;
}

return iconv('UTF-8', $encoding.'//IGNORE', $string);
}

private static function assertEncoding(string $encoding, string $errorFormat): void
{
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(\sprintf($errorFormat, $encoding));
throw new \ValueError(sprintf($errorFormat, $encoding));
}

// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(\sprintf($errorFormat, $encoding));
throw new \ValueError(sprintf($errorFormat, $encoding));
}
}
}
13 changes: 13 additions & 0 deletions src/Mbstring/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ function mb_ucfirst(string $string, ?string $encoding = null): string { return p
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}

if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}

if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}

if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}


if (extension_loaded('mbstring')) {
return;
}
Expand Down
12 changes: 12 additions & 0 deletions src/Mbstring/bootstrap80.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,18 @@ function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstri
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}

if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}

if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}

if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}

if (extension_loaded('mbstring')) {
return;
}
Expand Down
19 changes: 11 additions & 8 deletions src/Php72/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ function utf8_decode($string) { return p\Php72::utf8_decode($string); }
if (!function_exists('spl_object_id')) {
function spl_object_id($object) { return p\Php72::spl_object_id($object); }
}
if (!function_exists('mb_ord')) {
function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
}
if (!function_exists('mb_chr')) {
function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
}
if (!function_exists('mb_scrub')) {
function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }

if (extension_loaded('mbstring')) {
if (!function_exists('mb_ord')) {
function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
}
if (!function_exists('mb_chr')) {
function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
}
if (!function_exists('mb_scrub')) {
function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
}
}
8 changes: 5 additions & 3 deletions src/Php74/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
if (!function_exists('get_mangled_object_vars')) {
function get_mangled_object_vars($object) { return p\Php74::get_mangled_object_vars($object); }
}
if (!function_exists('mb_str_split') && function_exists('mb_substr')) {
function mb_str_split($string, $length = 1, $encoding = null) { return p\Php74::mb_str_split($string, $length, $encoding); }
}
if (!function_exists('password_algos')) {
function password_algos() { return p\Php74::password_algos(); }
}
if (extension_loaded('mbstring')) {
if (!function_exists('mb_str_split')) {
function mb_str_split($string, $length = 1, $encoding = null) { return p\Php74::mb_str_split($string, $length, $encoding); }
}
}
6 changes: 4 additions & 2 deletions src/Php83/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
function json_validate(string $json, int $depth = 512, int $flags = 0): bool { return p\Php83::json_validate($json, $depth, $flags); }
}

if (!function_exists('mb_str_pad') && function_exists('mb_substr')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
if (extension_loaded('mbstring')) {
if (!function_exists('mb_str_pad')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
}
}

if (!function_exists('stream_context_set_options')) {
Expand Down
62 changes: 62 additions & 0 deletions src/Php84/Php84.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/**
* @author Ayesh Karunaratne <ayesh@aye.sh>
* @author Pierre Ambroise <pierre27.ambroise@gmail.com>
*
* @internal
*/
Expand Down Expand Up @@ -107,4 +108,65 @@ public static function array_all(array $array, callable $callback): bool

return true;
}

public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}

public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
}

public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string
{
return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}

private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string
{
if (null === $encoding) {
$encoding = mb_internal_encoding();
}

try {
$validEncoding = @mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(sprintf('%s(): Argument #3 ($encoding) must be a valid encoding, "%s" given', $function, $encoding));
}

// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(sprintf('%s(): Argument #3 ($encoding) must be a valid encoding, "%s" given', $function, $encoding));
}

if ('' === $characters) {
return null === $encoding ? $string : mb_convert_encoding($string, $encoding);
}

if ('UTF-8' === $encoding || \in_array(strtolower($encoding), ['utf-8', 'utf8'], true)) {
$encoding = 'UTF-8';
}

$string = mb_convert_encoding($string, 'UTF-8', $encoding);

if (null !== $characters) {
$characters = mb_convert_encoding($characters, 'UTF-8', $encoding);
}

if (null === $characters) {
$characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}";
} else {
$characters = preg_quote($characters);
}

$string = preg_replace(sprintf($regex, $characters), '', $string);

if ('UTF-8' === $encoding) {
return $string;
}

return mb_convert_encoding($string, $encoding, 'UTF-8');
}
}
2 changes: 1 addition & 1 deletion src/Php84/Resources/stubs/Deprecated.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class Deprecated
{
public readonly ?string $message;
public readonly ?string $since;

public function __construct(?string $message = null, ?string $since = null)
{
$this->message = $message;
Expand Down
30 changes: 22 additions & 8 deletions src/Php84/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@
return;
}

if (!function_exists('mb_ucfirst')) {
function mb_ucfirst($string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); }
}

if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
}

if (!function_exists('array_find')) {
function array_find(array $array, callable $callback) { return p\Php84::array_find($array, $callback); }
}
Expand All @@ -38,3 +30,25 @@ function array_any(array $array, callable $callback): bool { return p\Php84::arr
if (!function_exists('array_all')) {
function array_all(array $array, callable $callback): bool { return p\Php84::array_all($array, $callback); }
}

if (extension_loaded('mbstring')) {
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst($string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); }
}

if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
}

if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_trim($string, $characters, $encoding); }
}

if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_ltrim($string, $characters, $encoding); }
}

if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_rtrim($string, $characters, $encoding); }
}
}
Loading
Loading