Re: cvs: ZendEngine2 / zend_builtin_functions.c

From: Date: Fri, 08 Apr 2005 17:08:49 +0000
Subject: Re: cvs: ZendEngine2 / zend_builtin_functions.c
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-15918@lists.php.net to get a copy of this message
Hi Andi, I am not a Refl API guru, but for the simple check of method_exists() one has to create one object and then iterate a result set. The other solution is get_class_methods() which again returns an array which has to be used only once - let's say with in_array(). in_array() is a bit slow because no hashing is used. What can be optimized is doing some caching in the memory but then the memory usage grows and grows. And a simple solution like method_exists() gives the answer directly. No complications to iterate over an array returned by reflection api or get_class_methods() and no additional memory allocated over and over and later probably cleaned by the gc. Why I am concerned about speed and memory usage? Since I may call method_exists() hundreds of times per script call and this will be a burden with a user-space solution. This is my POV. Andrey P.S. I have changed a bit the topic since my mail filter is not that smart :) Andi Gutmans wrote:
It's vital? Come on, you can convince me that it's nice to have, sure. But vital? What can it do which you can do with reflection API? If the name is sexier than you can write your own PHP function. At 06:36 PM 4/8/2005 +0200, Marcus Boerger wrote:
Hello Andrey, same goes for property_exists() which is why i added it. marcus Friday, April 8, 2005, 6:31:48 PM, you wrote:
Hello Andi, Marcus, method_exists() is quite vital to help where the type hinting fail. Type hinting fail because it leads to a fatal error which is
uncatchable
and the code cannot react on this. Therefore, for me type hinting is kind of useless since I cannot catch my bugs by executing some code
whenever
the data passed is not what the function/method expects. Reflection
API is
overkill to write everywhere and has to be wrapped to something
which at
the end will simulate method_exists().
Thanks for you attention, Andrey
Marcus Boerger wrote:
Hello Andi, to this i only agree under two conditions. First we remove other
like
method_exists() too and second we fix handling of implicit public and dynamic properties. Unless the second is done i see such a function as relative important and don't like to use reflection overhead always. regards marcus Friday, April 8, 2005, 6:00:03 PM, you wrote:
Marcus,
There was a long discussion about this a few months ago. The conclusion was to use the reflection_api for the very few
instances
where isset() isn't relevant. Although we have done bad stuff in the past, it's also not a good
idea to
continue polluting the global namespace. Please revert this patch. FYI, all the other requests for additional functions like class_constant_exists() should also be reflection API. It's best
for the
language.
Thanks, Andi
At 01:33 PM 4/8/2005 +0000, Marcus Boerger wrote:
helly           Fri Apr  8 09:33:17 2005 EDT
Modified files:
   /ZendEngine2        zend_builtin_functions.c
Log: - Add property_exits() http://cvs.php.net/diff.php/ZendEngine2/zend_builtin_functions.c?r1=1.
262&r2=1.263&ty=u
Index: ZendEngine2/zend_builtin_functions.c diff -u ZendEngine2/zend_builtin_functions.c:1.262 ZendEngine2/zend_builtin_functions.c:1.263 --- ZendEngine2/zend_builtin_functions.c:1.262 Mon Apr 4
13:23:38 2005
+++ ZendEngine2/zend_builtin_functions.c        Fri Apr  8 
09:33:15 2005
@@ -17,7 +17,7 @@ +----------------------------------------------------------------------+
*/ -/* $Id: zend_builtin_functions.c,v 1.262 2005/04/04 17:23:38 stas
Exp $ */
+/* $Id: zend_builtin_functions.c,v 1.263 2005/04/08 13:33:15
helly Exp $ */
#include "zend.h" #include "zend_API.h" @@ -43,6 +43,7 @@ static ZEND_FUNCTION(get_class); static ZEND_FUNCTION(get_parent_class); static ZEND_FUNCTION(method_exists); +static ZEND_FUNCTION(property_exists); static ZEND_FUNCTION(class_exists); static ZEND_FUNCTION(interface_exists); static ZEND_FUNCTION(function_exists); @@ -102,6 +103,7 @@
       ZEND_FE(get_class,                      NULL)
       ZEND_FE(get_parent_class,       NULL)
       ZEND_FE(method_exists,          NULL)
+       ZEND_FE(property_exists,        NULL)
       ZEND_FE(class_exists,           NULL)
       ZEND_FE(interface_exists,       NULL)
       ZEND_FE(function_exists,        NULL)
@@ -889,6 +891,63 @@ } /* }}} */ +/* {{{ proto bool property_exists(mixed object_or_class, string property_name) + Checks if the object or class has a property */ +ZEND_FUNCTION(property_exists) +{
+       zval **object, **property;
+       zend_class_entry *ce, **pce;
+       zend_property_info *property_info;
+       char *prop_name, *class_name;
+
+       if (ZEND_NUM_ARGS()!= 2 || zend_get_parameters_ex(2, &object,
&property)==FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+       convert_to_string_ex(property);
+
+       switch((*object)->type) {
+       case IS_STRING:
+               if (zend_lookup_class(Z_STRVAL_PP(object),
Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) {
+                       ce = *pce;
+               }
+               if (!ce) {
+                       RETURN_NULL();
+               }
+               if (!(property_info = zend_get_property_info(ce,
*property, 1 TSRMLS_CC)) || property_info == 
&EG(std_property_info)) {
+ RETURN_FALSE; + } + if (property_info->flags & ZEND_ACC_PUBLIC) { + RETURN_TRUE; + } + zend_unmangle_property_name(property_info->name, &class_name, &prop_name);
+               if (!strncmp(class_name, "*", 1)) {
+                       if (instanceof_function(EG(scope), ce 
TSRMLS_CC)) {
+ RETURN_TRUE; + } + RETURN_FALSE; + } + if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) {
+                       ce = *pce;
+               } else {
+                       RETURN_FALSE; /* shouldn't happen */
+               }
+               RETURN_BOOL(EG(scope) == ce);
+               RETURN_FALSE;
+
+       case IS_OBJECT:
+               if (Z_OBJ_HANDLER_PP(object, has_property) &&
Z_OBJ_HANDLER_PP(object, has_property)(*object, *property, 1 
TSRMLS_CC)) {
+ RETURN_TRUE; + } + RETURN_FALSE; +
+       default:
+               zend_error(E_WARNING, "Parameter must either be an 
object
or the name of an existing class");
+               RETURN_NULL();
+       }
+} +/* }}} */ + + /* {{{ proto bool class_exists(string classname [, bool autoload]) Checks if the class exists */ ZEND_FUNCTION(class_exists) -- Zend Engine CVS Mailing List (http://cvs.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
-- Best regards,
 Marcus                            mailto:mail@marcus-boerger.de


« previous php.internals (#15918) next »