php compare,PHP:__compare ?

在看《PHP之道》时有这么一段代码

$raw = '22. 11. 1968';

$start = \DateTime::createFromFormat('d. m. Y', $raw);

echo 'State date: ' . $start->format('m/d/Y') . "\n";

$end = clone $start;

$end->add(new \DateInterval('P1M6D'));

$diff = $end->diff($start);

echo "Difference: " . $diff->format('%m month, %d days (total: %a days)') . "\n";

if($start < $end) {

echo "Start is before end!\n";

}

`$start < $end` 引起了我的注意,印象中并没有__compare之类的魔术方法,翻了下手册确实没找到,也没相关实现,那为什么这里可以直接比较呢?

因为这是built-in class,所以需要翻一下源码。

已下的代码都是 PHP 5.4.27

已`compare`为关键字在 ext/date/php_date.c(DateTime在这实现)搜索,得到这么一个函数

static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC)

{

if (Z_TYPE_P(d1) == IS_OBJECT && Z_TYPE_P(d2) == IS_OBJECT &&

instanceof_function(Z_OBJCE_P(d1), date_ce_date TSRMLS_CC) &&

instanceof_function(Z_OBJCE_P(d2), date_ce_date TSRMLS_CC)) {

php_date_obj *o1 = zend_object_store_get_object(d1 TSRMLS_CC);

php_date_obj *o2 = zend_object_store_get_object(d2 TSRMLS_CC);

if (!o1->time || !o2->time) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to compare an incomplete DateTime object");

return 1;

}

if (!o1->time->sse_uptodate) {

timelib_update_ts(o1->time, o1->time->tz_info);

}

if (!o2->time->sse_uptodate) {

timelib_update_ts(o2->time, o2->time->tz_info);

}

return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);

}

return 1;

} 可以看出这就是__compare的实现部分,通过函数名继续搜索,来到line:1950

static void date_register_classes(TSRMLS_D)

{

zend_class_entry ce_date, ce_timezone, ce_interval, ce_period;

INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);

ce_date.create_object = date_object_new_date;

date_ce_date = zend_register_internal_class_ex(&ce_date, NULL, NULL TSRMLS_CC);

memcpy(&date_object_handlers_date, zend_get_std_object_handlers(), sizeof(zend_object_handlers));

date_object_handlers_date.clone_obj = date_object_clone_date;

date_object_handlers_date.compare_objects = date_object_compare_date;

date_object_handlers_date.get_properties = date_object_get_properties;

date_object_handlers_date.get_gc = date_object_get_gc;

..... date_object_handlers_date 是一个 zend_object_handlers,结构是这样的

struct _zend_object_handlers {

/* general object functions */

zend_object_add_ref_tadd_ref;

zend_object_del_ref_tdel_ref;

zend_object_clone_obj_tclone_obj;

/* individual object functions */

zend_object_read_property_tread_property;

zend_object_write_property_twrite_property;

zend_object_read_dimension_tread_dimension;

zend_object_write_dimension_twrite_dimension;

zend_object_get_property_ptr_ptr_tget_property_ptr_ptr;

zend_object_get_tget;

zend_object_set_tset;

zend_object_has_property_thas_property;

zend_object_unset_property_tunset_property;

zend_object_has_dimension_thas_dimension;

zend_object_unset_dimension_tunset_dimension;

zend_object_get_properties_tget_properties;

zend_object_get_method_tget_method;

zend_object_call_method_tcall_method;

zend_object_get_constructor_tget_constructor;

zend_object_get_class_entry_tget_class_entry;

zend_object_get_class_name_tget_class_name;

zend_object_compare_tcompare_objects;

zend_object_cast_tcast_object;

zend_object_count_elements_tcount_elements;

zend_object_get_debug_info_tget_debug_info;

zend_object_get_closure_tget_closure;

zend_object_get_gc_tget_gc;

}; 所以只有实现

zend_object_handlers.compare_objects才具备直接比较的功能,但这并没有暴露给用户层。

相关资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值