php natsort内核函数浅析第1/2页

2015-01-24信息快讯网

今天发现了php有个自然排序的函数----natsort,第一次听说了原来还有一种叫做“自然排序”的算法,很好奇

官方手册(http://us.php.net/manual/en/function.natsort.php

bool natsort ( array &$array ) 
This function implements a sort algorithm that orders alphanumeric strings in the way a human being would while maintaining key/value associations. This is described as a "natural ordering". An example of the difference between this algorithm and the regular computer string sorting algorithms (used in sort()) can be seen in the example below.

据官方手册还可以得到这样的结果:

img1.png img2.png img10.png img12.png

显然这很适合对类似文件名的排序。从结果看这种自然算法应该是去掉头和尾的非数字部分,然后对留下来的数字部分进行排序,究竟是不是,还是看一下php源码吧。
//从ext/standard/array.c抽取的相关代码如下 
static int php_array_natural_general_compare(const void *a, const void *b, int fold_case) /* {{{ */ 
{ 
    Bucket *f, *s; 
    zval *fval, *sval; 
    zval first, second; 
    int result; 
    f = *((Bucket **) a); 
    s = *((Bucket **) b); 
    fval = *((zval **) f->pData); 
    sval = *((zval **) s->pData); 
    first = *fval; 
    second = *sval; 
    if (Z_TYPE_P(fval) != IS_STRING) { 
        zval_copy_ctor(&first); 
        convert_to_string(&first); 
    } 
    if (Z_TYPE_P(sval) != IS_STRING) { 
        zval_copy_ctor(&second); 
        convert_to_string(&second); 
    } 
    result = strnatcmp_ex(Z_STRVAL(first), Z_STRLEN(first), Z_STRVAL(second), Z_STRLEN(second), fold_case); 
    if (Z_TYPE_P(fval) != IS_STRING) { 
        zval_dtor(&first); 
    } 
    if (Z_TYPE_P(sval) != IS_STRING) { 
        zval_dtor(&second); 
    } 
    return result; 
} 
/* }}} */ 
static int php_array_natural_compare(const void *a, const void *b TSRMLS_DC) /* {{{ */ 
{ 
    return php_array_natural_general_compare(a, b, 0); 
} 
/* }}} */ 
static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, int fold_case) /* {{{ */ 
{ 
    zval *array; 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { 
        return; 
    } 
    if (fold_case) { 
        if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_natural_case_compare, 0 TSRMLS_CC) == FAILURE) { 
            return; 
        } 
    } else { 
        if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_natural_compare, 0 TSRMLS_CC) == FAILURE) { 
            return; 
        } 
    } 
    RETURN_TRUE; 
} 
/* }}} */ 
/* {{{ proto void natsort(array &array_arg) 
Sort an array using natural sort */ 
PHP_FUNCTION(natsort) 
{ 
    php_natsort(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); 
} 
/* }}} */

虽然是第一次查看php的内核代码,不过凭借多年看代码的经验,还是很容易找到这个自然排序算法的核心就是函数:strnatcmp_ex(位于ext/standard/strnatcmp.c文件中)。
©2014-2024 dbsqp.com