3

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?

Community
  • 1
  • 1
Gábor Imre
  • 5,899
  • 2
  • 35
  • 48

2 Answers2

3

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
VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • I don't know how to provide the very same functionality in JavaScript. Thanks for the idea though, I'll look around `intl`. – Gábor Imre Aug 28 '15 at 15:25
-1

you have strcmp

int strcmp ( string $str1 , string $str2 )

Returns 0 if the same string < 0 if smaller and > 0 if bigger

I_G
  • 413
  • 1
  • 4
  • 18