Skip to content
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

[PHP 8.4][Intl] Add grapheme_str_split #483

Open
wants to merge 1 commit into
base: 1.x
Choose a base branch
from

Conversation

Ayesh
Copy link
Contributor

@Ayesh Ayesh commented Jun 5, 2024

Adds a polyfill for the grapheme_str_split function added in PHP 8.4.

Requires PHP 7.3, because the polyfill is based on \X Regex, and it only works properly on PCRE2, which only comes with PHP 7.3+.

Further, there are some cases that the polyfill cannot split complex characters (such as two consecutive country flag Emojis). This is now fixed in PCRE2Project/pcre2#410. However, this change will likely only make it to PHP 8.4.

References:

@Ayesh
Copy link
Contributor Author

Ayesh commented Jun 5, 2024

(working on the Intl changes, I'll mark the PR ready then)

@derrabus
Copy link
Member

derrabus commented Jun 5, 2024

Thank you. I think, we should add this polyfill to the intl-grapheme polyfill as well.

@Ayesh Ayesh force-pushed the grapheme_str_split branch 2 times, most recently from 75b1867 to 123cf13 Compare June 8, 2024 10:18
Add a polyfill for the `grapheme_str_split` function added in PHP 8.4.

Requires PHP 7.3, because the polyfill is based on `\X` Regex, and it
only works properly on PCRE2, which
[only comes with PHP 7.3+](https://php.watch/versions/7.3/pcre2).

Further, there are some cases that the polyfill cannot split complex
characters (such as two consecutive country flag Emojis). This is now
fixed in [PCRE2Project/pcre2#410](PCRE2Project/pcre2#410).
However, this change will likely only make it to PHP 8.4.

References:
 - [RFC: Grapheme cluster for `str_split` function: `grapheme_str_split`](https://wiki.php.net/rfc/grapheme_str_split)
 - [PHP.Watch: PHP 8.4: New `grapheme_str_split` function](https://php.watch/versions/8.4/grapheme_str_split)
@Ayesh Ayesh marked this pull request as ready for review June 8, 2024 10:21
@Ayesh
Copy link
Contributor Author

Ayesh commented Jun 8, 2024

Thank you @derrabus - I added polyfill and tests for grapheme_str_split to the Intl polyfill too.

@@ -68,6 +68,7 @@ Polyfills are provided for:
- the `Date*Exception/Error` classes introduced in PHP 8.3;
- the `SQLite3Exception` class introduced in PHP 8.3;
- the `mb_ucfirst` and `mb_lcfirst` functions introduced in PHP 8.4;
- the `grapheme_str_split` function introduced in PHP 8.4 (requires PHP >= 7.3);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove the need for PHP 7.3 as that makes the polyfill dangerous IMHO
Instead, we can borrow from SYMFONY_GRAPHEME_CLUSTER_RX as defined in the intl-grapheme polyfill
we can copy/paste the string I think


preg_match_all('/\X/u', $s, $matches);

if (empty($matches[0])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please avoid using empty

return false;
}

if ($len === 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use yoda style everywhere (I can fix that using php-cs-fixer, there are way more things to fix, cs-wise)


$chunks = array_chunk($matches[0], $len);

array_walk($chunks, static function(&$value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure using a foreach is going to be faster here: not need for one function call per iteration

@@ -56,3 +56,7 @@ function grapheme_strstr($haystack, $needle, $beforeNeedle = false) { return p\G
if (!function_exists('grapheme_substr')) {
function grapheme_substr($string, $offset, $length = null) { return p\Grapheme::grapheme_substr($string, $offset, $length); }
}

if (\PHP_VERSION_ID >= 70300) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be removed following my comment above

use Symfony\Polyfill\Php84 as p;

if (!function_exists('grapheme_str_split') && function_exists('grapheme_substr')) {
function grapheme_str_split(string $string, int $length = 1) { return p\Php84::grapheme_str_split($string, $length); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be moved to bootstrap.php following my comment above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants