Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String comparison: something identical of JavaScript's localeCompare in PHP?

Is there any solution to have a string comparison function in PHP identical to JavaScript's string.localeCompare()?

My goal is to make a hasher that can be applied over simple objects in PHP and in JS as well. The property ordering can be solved based on this question: Sorting JavaScript Object by property value

I make a list of property key and value tuplets and I order the list by the keys. (Note that this can work recursively too.) But I'm a bit afraid of string representations and locales, that they might be tricky. If the property keys contain some fancy characters then the sorting may be different in PHP and JS side, resulting in different hashes.

Try the following in PHP, and make a similar comparison in JS.

echo strcmp('e', 'é')."\n";
echo strcmp('e', 'ě')."\n";
echo strcmp('é', 'ě')."\n";
echo strcmp('e', 'f')."\n";
echo strcmp('é', 'f')."\n"; // This will differ
echo strcmp('ě', 'f')."\n"; // This will differ

Main question: how can I perform identical string comparison in PHP and JS?

Side question: Other ideas for object hashing in PHP and JS?

like image 859
Gábor Imre Avatar asked Mar 25 '26 03:03

Gábor Imre


1 Answers

Take a look at the intl extension.

e.g.

<?php
// the intl extensions works on unicode strings
// so this is my way to ensure this example uses utf-8
define('LATIN_SMALL_LETTER_E_WITH_ACUTE', chr(0xc3).chr(0xa9));
define('LATIN_SMALL_LETTER_E_WITH_CARON', chr(0xc4).chr(0x9b));
ini_set('default_charset', 'utf-8');
$chars = [
    'e',
    LATIN_SMALL_LETTER_E_WITH_ACUTE,
    LATIN_SMALL_LETTER_E_WITH_CARON,
    'f'
];

$col = Collator::create(null);  // the default rules will do in this case..
$col->setStrength(Collator::PRIMARY); // only compare base characters; not accents, lower/upper-case, ...

for($i=0; $i<count($chars)-1; $i++) {
    for($j=$i; $j<count($chars); $j++) {
        echo $chars[$i], ' ', $chars[$j], ' ',
            $col->compare($chars[$i], $chars[$j]),
            "<br />\r\n";
    }
}

prints

e e 0
e é 0
e ě 0
e f -1
é é 0
é ě 0
é f -1
ě ě 0
ě f -1
like image 55
VolkerK Avatar answered Mar 26 '26 15:03

VolkerK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!