Locale Based Array sorting

From: Date: Fri, 10 Sep 2004 11:20:28 +0000
Subject: Locale Based Array sorting
Groups: php.internals 
Request: Send a blank email to internals+get-12713@lists.php.net to get a copy of this message
Hello, the attached patch adds a flag (SORT_LOCALE_STRING) to our sort functions that allows the sorting to be done based on the locale settings. This is important for languages like Norwegian which adds æ, ø and å to the end of the alphabet, while their iso-8859-1 (the "C" locale) order is å æ ø. The working is demonstrated as follows: <?php $a = array("ætte", "åtte", "øtte"); $d = $c = $b = $a; setlocale(LC_ALL, 'C'); sort($a); sort($b, SORT_LOCALE_STRING); var_dump($b); setlocale(LC_ALL, 'no_NO'); sort($c, SORT_LOCALE_STRING); var_dump($c); // Words in UTF-8 $d = array("Ã¥tte", "Þtte2", "Êtte4", "Þtte1", "Êtte3"); setlocale(LC_ALL, 'no_NO.UTF-8'); sort($d, SORT_LOCALE_STRING); var_dump($d); ?> Output: array(3) { [0]=> string(4) "åtte" [1]=> string(4) "ætte" [2]=> string(4) "øtte" } array(3) { [0]=> string(4) "ætte" [1]=> string(4) "øtte" [2]=> string(4) "åtte" } array(5) { [0]=> string(6) "Êtte3" [1]=> string(6) "Êtte4" [2]=> string(6) "Þtte1" [3]=> string(6) "Þtte2" [4]=> string(5) "Ã¥tte" } (The funny chars are UTf8, but it is correct sorting) I will be committing this patch later, if there are no objections. Derick -- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

? Zend Index: ext/standard/array.c =================================================================== RCS file: /repository/php-src/ext/standard/array.c,v retrieving revision 1.266.2.2 diff -u -p -r1.266.2.2 array.c --- ext/standard/array.c 10 Aug 2004 06:01:20 -0000 1.266.2.2 +++ ext/standard/array.c 10 Sep 2004 10:46:27 -0000 @@ -65,6 +65,7 @@ php_array_globals array_globals; #define SORT_REGULAR 0 #define SORT_NUMERIC 1 #define SORT_STRING 2 +#define SORT_LOCALE_STRING 5 #define SORT_DESC 3 #define SORT_ASC 4 @@ -112,6 +113,8 @@ PHP_MINIT_FUNCTION(array) REGISTER_LONG_CONSTANT("SORT_REGULAR", SORT_REGULAR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_NUMERIC", SORT_NUMERIC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_STRING", SORT_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SORT_LOCALE_STRING", SORT_LOCALE_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CASE_LOWER", CASE_LOWER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CASE_UPPER", CASE_UPPER, CONST_CS | CONST_PERSISTENT); @@ -141,6 +144,10 @@ static void set_compare_func(int sort_ty ARRAYG(compare_func) = string_compare_function; break; + case SORT_LOCALE_STRING: + ARRAYG(compare_func) = string_locale_compare_function; + break; + case SORT_REGULAR: default: ARRAYG(compare_func) = compare_function; Index: Zend/zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.193 diff -u -p -r1.193 zend_operators.c --- Zend/zend_operators.c 10 May 2004 14:56:21 -0000 1.193 +++ Zend/zend_operators.c 10 Sep 2004 10:49:08 -0000 @@ -1221,6 +1221,33 @@ ZEND_API int string_compare_function(zva return SUCCESS; } +ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) +{ + zval op1_copy, op2_copy; + int use_copy1, use_copy2; + + zend_make_printable_zval(op1, &op1_copy, &use_copy1); + zend_make_printable_zval(op2, &op2_copy, &use_copy2); + + if (use_copy1) { + op1 = &op1_copy; + } + if (use_copy2) { + op2 = &op2_copy; + } + + result->value.lval = strcoll(op1->value.str.val, op2->value.str.val); + result->type = IS_LONG; + + if (use_copy1) { + zval_dtor(op1); + } + if (use_copy2) { + zval_dtor(op2); + } + return SUCCESS; +} + ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) { zval op1_copy, op2_copy; Index: Zend/zend_operators.h =================================================================== RCS file: /repository/ZendEngine2/zend_operators.h,v retrieving revision 1.88.2.1 diff -u -p -r1.88.2.1 zend_operators.h --- Zend/zend_operators.h 16 Jul 2004 02:02:09 -0000 1.88.2.1 +++ Zend/zend_operators.h 10 Sep 2004 10:49:08 -0000 @@ -179,6 +179,7 @@ ZEND_API int zval_is_true(zval *op); ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); +ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API void zend_str_tolower(char *str, unsigned int length); ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
« previous php.internals (#12713) next »