⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overload.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	int got_prop = 0;	TSRMLS_FETCH();	INIT_PZVAL(result_ptr);	for (element=property_reference->elements_list->head; element; element=element->next) {		overloaded_property = (zend_overloaded_element *) element->data;		ZVAL_NULL(result_ptr);		if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) {			/* Trying to access a property on a non-object. */			if (Z_TYPE(object) != IS_OBJECT) {				CLEANUP_OO_CHAIN();				if (got_prop)					zval_dtor(&object);				return result;			}			if (zend_hash_find(Z_OBJPROP(object),							   Z_STRVAL(overloaded_property->element),							   Z_STRLEN(overloaded_property->element)+1,							   (void **)&real_prop) == SUCCESS) {				result = **real_prop;				/* printf("is_ref: %d, refcount: %d\n", (*real_prop)->is_ref, (*real_prop)->refcount); */				/* REPLACE_ZVAL_VALUE(&result_ptr, *real_prop, 1); */			} else if (Z_OBJCE(object)->handle_property_get == overload_get_property &&					   call_get_handler(&object,										&overloaded_property->element,										&result_ptr TSRMLS_CC)) {				got_prop = 1;			} else {				php_error(E_NOTICE, "Undefined property: %s", Z_STRVAL(overloaded_property->element));					CLEANUP_OO_CHAIN();				if (got_prop)					zval_dtor(&object);				return result;			}		} else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) {			/* Trying to access index on a non-array. */			if (Z_TYPE(object) != IS_ARRAY) {				CLEANUP_OO_CHAIN();				if (got_prop)					zval_dtor(&object);				return result;			}			if (Z_TYPE(overloaded_property->element) == IS_STRING) {				if (zend_hash_find(Z_ARRVAL(object),								   Z_STRVAL(overloaded_property->element),								   Z_STRLEN(overloaded_property->element)+1,								   (void **)&real_prop) == FAILURE) {					CLEANUP_OO_CHAIN();					if (got_prop)						zval_dtor(&object);					return result;				}			} else if (Z_TYPE(overloaded_property->element) == IS_LONG) {				if (zend_hash_index_find(Z_ARRVAL(object),										  Z_LVAL(overloaded_property->element),										  (void **)&real_prop) == FAILURE) {					CLEANUP_OO_CHAIN();					if (got_prop)						zval_dtor(&object);					return result;				}			}			result = **real_prop;		}		zval_dtor(&overloaded_property->element);		/* printf("got_prop: %d\n", got_prop); */		if (element != property_reference->elements_list->head && got_prop) {			zval_dtor(&object);			got_prop = 0;		}		object = result;	}	if (!got_prop)		zval_copy_ctor(&result);	return result;}/* }}} *//* {{{ int overload_set_property() */static int overload_set_property(zend_property_reference *property_reference, zval *value){	zval result;	zval *result_ptr = &result;	zend_overloaded_element *overloaded_property;	zend_llist_element *element;	zval **object = &property_reference->object;	TSRMLS_FETCH();	for (element=property_reference->elements_list->head; element; element=element->next) {		overloaded_property = (zend_overloaded_element *) element->data;		ZVAL_NULL(result_ptr);		if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) {			/* Trying to access a property on a non-object. */			if (Z_TYPE_PP(object) != IS_OBJECT) {				CLEANUP_OO_CHAIN();				return FAILURE;			} 						if (zend_hash_find(Z_OBJPROP_PP(object),							   Z_STRVAL(overloaded_property->element),							   Z_STRLEN(overloaded_property->element)+1,							   (void **)&object) == FAILURE) {				if (element == property_reference->elements_list->tail) {					if (Z_OBJCE_PP(object)->handle_property_set == overload_set_property &&						call_set_handler(*object,										  &overloaded_property->element,										  value TSRMLS_CC)) {						CLEANUP_OO_CHAIN();						return SUCCESS;					} else {						php_error(E_WARNING, "Unable to set property: %s", Z_STRVAL(overloaded_property->element));						CLEANUP_OO_CHAIN();						return FAILURE;					}				}				if (Z_OBJCE_PP(object)->handle_property_get == overload_get_property &&					call_get_handler(*object,									 &overloaded_property->element,									 &result_ptr TSRMLS_CC)) {					object = &result_ptr;				} else {					php_error(E_NOTICE, "Undefined property: %s", Z_STRVAL(overloaded_property->element));						CLEANUP_OO_CHAIN();					return FAILURE;				}			}		} else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) {		}		zval_dtor(&overloaded_property->element);	}	/* printf("value is_ref: %d, refcount: %d\n", value->is_ref, value->refcount); */	REPLACE_ZVAL_VALUE(object, value, 1);	/* printf("object is_ref: %d, refcount: %d\n", (*object)->is_ref, (*object)->refcount); */	return SUCCESS;}/* }}} *//* {{{ void overload_call_method() */static void overload_call_method(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference){	zval ***args;	zval *retval = NULL;	int call_result;	zend_bool use_call_handler = 1;	zval *object = property_reference->object;	zval call_handler, method_name, *method_name_ptr = &method_name;	zend_overloaded_element *method = (zend_overloaded_element *)property_reference->elements_list->tail->data;	/*	 * We don't use the call handler if the invoked method exists in object's	 * method table.	 */	if (zend_hash_exists(&Z_OBJCE_P(object)->function_table,						 Z_STRVAL(method->element),						 Z_STRLEN(method->element) + 1)) {		use_call_handler = 0;	}	args = (zval ***)emalloc(ZEND_NUM_ARGS() * sizeof(zval **));	if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {		efree(args);		php_error(E_WARNING, "unable to obtain arguments");		return;	}	if (use_call_handler) {		zval **handler_args[3];		zval *arg_array;		zval result, *result_ptr = &result;		zend_class_entry temp_ce, *orig_ce;		int i;		temp_ce = *Z_OBJCE_P(object);		DISABLE_HANDLERS(temp_ce);		orig_ce = Z_OBJCE_P(object);		Z_OBJ_P(object)->ce = &temp_ce;		ZVAL_STRINGL(&call_handler, CALL_HANDLER, sizeof(CALL_HANDLER)-1, 0);		ZVAL_STRINGL(&method_name, Z_STRVAL(method->element), Z_STRLEN(method->element), 0);		INIT_PZVAL(&call_handler);		INIT_PZVAL(method_name_ptr);		MAKE_STD_ZVAL(arg_array);		array_init(arg_array);		for (i = 0; i < ZEND_NUM_ARGS(); i++) {			zval_add_ref(args[i]);			add_next_index_zval(arg_array, *args[i]);		}		result_ptr->is_ref = 1;		result_ptr->refcount = 1;		ZVAL_NULL(result_ptr);				handler_args[0] = &method_name_ptr;		handler_args[1] = &arg_array;		handler_args[2] = &result_ptr;		call_result = call_user_function_ex(NULL,											&object,											&call_handler,											&retval,											3, handler_args,											0, NULL TSRMLS_CC);		Z_OBJ_P(object)->ce = orig_ce;		zval_ptr_dtor(&arg_array);		if (call_result == FAILURE || !retval) {			efree(args);			zval_dtor(result_ptr);			php_error(E_WARNING, "unable to call %s::" CALL_HANDLER "() handler", Z_OBJCE_P(object)->name);			return;		}		if (zval_is_true(retval)) {			REPLACE_ZVAL_VALUE(&return_value, result_ptr, 1);		} else {			zval_dtor(result_ptr);			php_error(E_WARNING, "Call to undefined method %s::%s()", Z_OBJCE_P(object)->name, Z_STRVAL(method_name));		}		zval_ptr_dtor(&retval);	} else {		call_result = call_user_function_ex(NULL,											&object,											&method->element,											&retval,											ZEND_NUM_ARGS(), args,											0, NULL TSRMLS_CC);		if (call_result == FAILURE || !retval) {			efree(args);			php_error(E_WARNING, "unable to call %s::%s() method", Z_OBJCE_P(object)->name, Z_STRVAL(method->element));			return;		}		REPLACE_ZVAL_VALUE(&return_value, retval, 1);		zval_ptr_dtor(&retval);	}		efree(args);	zval_dtor(&method->element);}/* }}} *//* {{{ static int locate_accessors() */static int locate_accessors(zend_function *method, oo_class_data *oo_data TSRMLS_DC){	zval *accessor_name;	char *function_name = method->common.function_name;	int function_name_len = strlen(method->common.function_name);	if (!strncmp(function_name, GET_HANDLER "_", sizeof(GET_HANDLER "_")-1)) {		MAKE_STD_ZVAL(accessor_name);		ZVAL_STRINGL(accessor_name, function_name, function_name_len, 1);		zend_hash_update(&oo_data->getters,						 function_name + sizeof(GET_HANDLER "_") - 1, 						 function_name_len - sizeof(GET_HANDLER "_") + 2,						 (void *)&accessor_name, sizeof(zval *), NULL);	} else if (!strncmp(function_name, SET_HANDLER "_", sizeof(SET_HANDLER "_")-1)) {		MAKE_STD_ZVAL(accessor_name);		ZVAL_STRINGL(accessor_name, function_name, function_name_len, 1);		zend_hash_update(&oo_data->setters,						 function_name + sizeof(SET_HANDLER "_") - 1, 						 function_name_len - sizeof(SET_HANDLER "_") + 2,						 (void *)&accessor_name, sizeof(zval *), NULL);	}	return 0;}/* }}} *//* {{{ proto void overload(string class_entry)    Enables property and method call overloading for a class. */PHP_FUNCTION(overload){	char *class_entry = NULL;	int argc = ZEND_NUM_ARGS();	int class_entry_len;	zend_class_entry *ce = NULL;	oo_class_data oo_data;	if (zend_parse_parameters(argc TSRMLS_CC, "s/", &class_entry, &class_entry_len) == FAILURE) 		return;	zend_str_tolower(class_entry, class_entry_len);	if (zend_hash_find(EG(class_table), class_entry, class_entry_len+1, (void**)&ce) == FAILURE) {		php_error(E_WARNING, "%s() was unable to locate class '%s'", get_active_function_name(TSRMLS_C), class_entry);		RETURN_FALSE;	}	/* Check if the handlers have already been installed for this class. */	if (zend_hash_index_exists(&OOG(overloaded_classes), (long)ce)) {		RETURN_TRUE;	}	zend_hash_init(&oo_data.getters, 10, NULL, ZVAL_PTR_DTOR, 0);	zend_hash_init(&oo_data.setters, 10, NULL, ZVAL_PTR_DTOR, 0);	zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)locate_accessors, (void *)&oo_data TSRMLS_CC);		if (zend_hash_exists(&ce->function_table, GET_HANDLER, sizeof(GET_HANDLER)) ||		zend_hash_num_elements(&oo_data.getters)) {		oo_data.handle_property_get = ce->handle_property_get;		ce->handle_property_get = overload_get_property;	} else		oo_data.handle_property_get = NULL;	if (zend_hash_exists(&ce->function_table, SET_HANDLER, sizeof(SET_HANDLER)) ||		zend_hash_num_elements(&oo_data.setters)) {		oo_data.handle_property_set = ce->handle_property_set;		ce->handle_property_set = overload_set_property;	} else		oo_data.handle_property_set = NULL;	if (zend_hash_exists(&ce->function_table, CALL_HANDLER, sizeof(CALL_HANDLER))) {		oo_data.handle_function_call = ce->handle_function_call;		ce->handle_function_call = overload_call_method;	} else		oo_data.handle_function_call = NULL;	zend_hash_index_update(&OOG(overloaded_classes), (long)ce, &oo_data, sizeof(oo_data), NULL);	RETURN_TRUE;}/* }}} */#endif /* HAVE_OVERLOAD */#endif /* ZEND_ENGINE_2 *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -