php比较函数

最近浏览PHP语言的源码-比较函数php

其实我说的比较函数不是字符串比较,并且当我用PHP 的数组排序时候须要比较函数web

1,为何用比较函数数组

   首先用比较函数的好处就是代码的抽象,其实就是只有知足比较函数的规则你就能够,按照你本身方式排序,不是降序和升序这些简单的规则!知足规则{-1,0,1}-1:表明是小于,0表明等于,1表明大小app

2.用比较函数tcp

ZEND_API int compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
        int ret;
        int converted = 0;
        zval op1_copy, op2_copy;
        zval *op_free, tmp_free;

        while (1) {
                switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
                        case TYPE_PAIR(IS_LONG, IS_LONG):
                                ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
                                return SUCCESS;

                        case TYPE_PAIR(IS_DOUBLE, IS_LONG):
                                Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
                                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                                return SUCCESS;

                        case TYPE_PAIR(IS_LONG, IS_DOUBLE):
                                Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
                                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                                return SUCCESS;
                           case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
                                if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
                                        ZVAL_LONG(result, 0);
                                } else {
                                        Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
                                        ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                                }
                                return SUCCESS;

                        case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
                                ZVAL_LONG(result, zend_compare_arrays(op1, op2));
                                return SUCCESS;

                        case TYPE_PAIR(IS_NULL, IS_NULL):
                        case TYPE_PAIR(IS_NULL, IS_FALSE):
                        case TYPE_PAIR(IS_FALSE, IS_NULL):
                        case TYPE_PAIR(IS_FALSE, IS_FALSE):
                        case TYPE_PAIR(IS_TRUE, IS_TRUE):
                                ZVAL_LONG(result, 0);
                                return SUCCESS;

                        case TYPE_PAIR(IS_NULL, IS_TRUE):
                                ZVAL_LONG(result, -1);
                                return SUCCESS;

                        case TYPE_PAIR(IS_TRUE, IS_NULL):
                                ZVAL_LONG(result, 1);
                                return SUCCESS;

                        case TYPE_PAIR(IS_STRING, IS_STRING):
                                if (Z_STR_P(op1) == Z_STR_P(op2)) {
                                        ZVAL_LONG(result, 0);
                                        return SUCCESS;
                                }
                                ZVAL_LONG(result, zendi_smart_strcmp(op1, op2));
                                return SUCCESS;

                        case TYPE_PAIR(IS_NULL, IS_STRING):
                                ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
                                return SUCCESS;
                        case TYPE_PAIR(IS_NULL, IS_STRING):
                                ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
                                return SUCCESS;

                        case TYPE_PAIR(IS_STRING, IS_NULL):
                                ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
                                return SUCCESS;

                        case TYPE_PAIR(IS_OBJECT, IS_NULL):
                                ZVAL_LONG(result, 1);
                                return SUCCESS;

                        case TYPE_PAIR(IS_NULL, IS_OBJECT):
                                ZVAL_LONG(result, -1);
                                return SUCCESS;

                        default:
                                if (Z_ISREF_P(op1)) {
                                        op1 = Z_REFVAL_P(op1);
                                        continue;
                                } else if (Z_ISREF_P(op2)) {
                                        op2 = Z_REFVAL_P(op2);
                                        continue;
                                }
                                if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
                                        return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
                                } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
                                        return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
                                }

                                if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
                                        if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
                                                /* object handles are identical, apparently this is the same object */
                                                ZVAL_LONG(result, 0);
                                                return SUCCESS;
                                        }
                                        if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
                                                ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2));
                                                return SUCCESS;
                                        }
                                }
                                if (Z_TYPE_P(op1) == IS_OBJECT) {
                                        if (Z_OBJ_HT_P(op1)->get) {
                                                zval rv;
                                                op_free = Z_OBJ_HT_P(op1)->get(op1, &rv);
                                                ret = compare_function(result, op_free, op2);
                                                zend_free_obj_get_result(op_free);
                                                return ret;
                                        } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
                                                ZVAL_UNDEF(&tmp_free);
                                                if (Z_OBJ_HT_P(op1)->cast_object(op1, &tmp_free, ((Z_TYPE_P(op2) == IS_FALSE || Z_TYPE_P(op2) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op2))) == FAILURE) {
                                                        ZVAL_LONG(result, 1);
                                                        zend_free_obj_get_result(&tmp_free);
                                                        return SUCCESS;
                                                }
                                                ret = compare_function(result, &tmp_free, op2);
                                                zend_free_obj_get_result(&tmp_free);
                                                return ret;
                                        }
                                }
                                if (Z_TYPE_P(op2) == IS_OBJECT) {
                                        if (Z_OBJ_HT_P(op2)->get) {
                                                zval rv;
                                                op_free = Z_OBJ_HT_P(op2)->get(op2, &rv);
                                                ret = compare_function(result, op1, op_free);
                                                zend_free_obj_get_result(op_free);
                                                return ret;
                                        } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
                                                ZVAL_UNDEF(&tmp_free);
                                                if (Z_OBJ_HT_P(op2)->cast_object(op2, &tmp_free, ((Z_TYPE_P(op1) == IS_FALSE || Z_TYPE_P(op1) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op1))) == FAILURE) {
                                                        ZVAL_LONG(result, -1);
                                                        zend_free_obj_get_result(&tmp_free);
                                                        return SUCCESS;
                                                }
                                                ret = compare_function(result, op1, &tmp_free);
                                                zend_free_obj_get_result(&tmp_free);
                                                return ret;
                                        } else if (Z_TYPE_P(op1) == IS_OBJECT) {
                                                ZVAL_LONG(result, 1);
                                                return SUCCESS;
                                        }
                                }
                                if (!converted) {
                                        if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
                                                ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
                                                return SUCCESS;
                                        } else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
                                                ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
                                                return SUCCESS;
                                        } else if (Z_TYPE_P(op1) == IS_TRUE) {
                                                ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
                                                return SUCCESS;
                                        } else if (Z_TYPE_P(op2) == IS_TRUE) {
                                                ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
                                                return SUCCESS;
                                        } else {
                                                zendi_convert_scalar_to_number(op1, op1_copy, result);
                                                zendi_convert_scalar_to_number(op2, op2_copy, result);
                                                converted = 1;
                                        }
                                         } else if (Z_TYPE_P(op1)==IS_ARRAY) {
                                        ZVAL_LONG(result, 1);
                                        return SUCCESS;
                                } else if (Z_TYPE_P(op2)==IS_ARRAY) {
                                        ZVAL_LONG(result, -1);
                                        return SUCCESS;
                                } else if (Z_TYPE_P(op1)==IS_OBJECT) {
                                        ZVAL_LONG(result, 1);
                                        return SUCCESS;
                                } else if (Z_TYPE_P(op2)==IS_OBJECT) {
                                        ZVAL_LONG(result, -1);
                                        return SUCCESS;
                                } else {
                                        ZVAL_LONG(result, 0);
                                        return FAILURE;
                                }
                }
        }
}

3.总结ide

       其实通常人认为比较函数很简单:就返回-1,0,1比较能够吗,为何写的那么长。首选,php是弱类型语言,咱们不能肯定咱们要比较两个数 是什么类型,好比数字,数字又分整型,浮点型,长整型,字符串,空等因而就注定长PHP的2个PHP的类型的个数= 2^(PHP类型的个数)函数

这就是一门语言,受欢迎的语言,考虑的方面比较多,全面性,this

一门语言存在时间越长越长,它的补丁就越多,这个是在实践中检验出来的!你问它为何,有可能它也不知道,反正就这样这个问题能够避免,有可能为了环境,你确定见过#if HAVE_STRCOLL #endif 等等,也有可能避免它用函数的bug,也有可能每次对代码的抽象的不一样,反正就源码就是一个难懂,难懂后面你能够看到一门语言的背后的故事,其实底层和咱们作应用层原理同样,就是经过已有创造出咱们想要东西,好比应用层:咱们能够用php语言写一个web页面,底层只不过用c语言写一个tcp/ip 的写协议,scala

相关文章
相关标签/搜索