ID:               24274
 Comment by:       torben at thebuttlesschaps dot com
 Reported By:      [EMAIL PROTECTED]
 Status:           Open
 Bug Type:         Feature/Change Request
 Operating System: All
 PHP Version:      4CVS-2003-06-20 (stable)
 New Comment:

Hmm. A non-messed-up patch can be found here:

 http://www.thebuttlesschaps.com/variable_exists_patch.txt


Torben


Previous Comments:
------------------------------------------------------------------------

[2003-06-20 17:08:17] [EMAIL PROTECTED]

Description:
------------
PHP doesn't have a way to check whether a variable exists; just a way
to check whether it has a value (isset()). This isn't wrong, but it
would be useful to add a way to check for actual existence of a
variable (for instance, checking for array keys without having to go
through array_key_exists()).

Here's a patch against CVS which implements variable_exists(). The only
difference to isset() is that a variable is considered to exist even if
it contains NULL.


Index: zend_compile.h
===================================================================
RCS file: /repository/Zend/zend_compile.h,v
retrieving revision 1.145
diff -u -r1.145 zend_compile.h
--- zend_compile.h      31 Dec 2002 15:55:02 -0000      1.145
+++ zend_compile.h      20 Jun 2003 11:35:20 -0000
@@ -558,6 +558,7 @@
 
 #define ZEND_ISSET                             (1<<0)
 #define ZEND_ISEMPTY                   (1<<1)
+#define ZEND_VARIABLE_EXISTS    (1<<2)
 
 #define ZEND_CT        (1<<0)
 #define ZEND_RT (1<<1)
Index: zend_execute.c
===================================================================
RCS file: /repository/Zend/zend_execute.c,v
retrieving revision 1.321
diff -u -r1.321 zend_execute.c
--- zend_execute.c      31 Dec 2002 15:55:02 -0000      1.321
+++ zend_execute.c      20 Jun 2003 11:35:22 -0000
@@ -2382,7 +2382,7 @@
                                                                isset = 1;
                                                        }
                                                }
-                                       } else if (*var==EG(uninitialized_zval_ptr) || 
((*var)->type ==
IS_NULL)) {
+                                       } else if (*var == EG(uninitialized_zval_ptr) 
|| (((*var)->type
== IS_NULL) && EX(opline)->op2.u.constant.value.lval !=
ZEND_VARIABLE_EXISTS)) { 
                                                value = *var;
                                                isset = 0;
                                        } else {
@@ -2391,6 +2391,7 @@
                                        }
 
                                        switch (EX(opline)->op2.u.constant.value.lval) 
{
+                                               case ZEND_VARIABLE_EXISTS:
                                                case ZEND_ISSET:
                                                        
EX(Ts)[EX(opline)->result.u.var].tmp_var.value.lval = isset;
                                                        break;
Index: zend_language_parser.y
===================================================================
RCS file: /repository/Zend/zend_language_parser.y,v
retrieving revision 1.23
diff -u -r1.23 zend_language_parser.y
--- zend_language_parser.y      4 Aug 2002 06:39:44 -0000       1.23
+++ zend_language_parser.y      20 Jun 2003 11:35:22 -0000
@@ -112,6 +112,7 @@
 %token T_UNSET
 %token T_ISSET
 %token T_EMPTY
+%token T_VARIABLE_EXISTS
 %token T_CLASS
 %token T_EXTENDS
 %token T_OBJECT_OPERATOR
@@ -710,6 +711,7 @@
 
 internal_functions_in_yacc:
                T_ISSET '(' isset_variables ')' { $$ = $3; }
+       |       T_VARIABLE_EXISTS '(' variable_exists_variables ')' { $$ = $3; }
        |       T_EMPTY '(' cvar ')'    { zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$,
&$3 TSRMLS_CC); }
        |       T_INCLUDE expr                  { 
zend_do_include_or_eval(ZEND_INCLUDE, &$$, &$2
TSRMLS_CC); }
        |       T_INCLUDE_ONCE expr     { zend_do_include_or_eval(ZEND_INCLUDE_ONCE,
&$$, &$2 TSRMLS_CC); }
@@ -717,6 +719,11 @@
        |       T_REQUIRE expr                  { 
zend_do_include_or_eval(ZEND_REQUIRE, &$$, &$2
TSRMLS_CC); }
        |       T_REQUIRE_ONCE expr             { 
zend_do_include_or_eval(ZEND_REQUIRE_ONCE,
&$$, &$2 TSRMLS_CC); }
 ;
+
+variable_exists_variables:
+               cvar                                                    { 
zend_do_isset_or_isempty(ZEND_VARIABLE_EXISTS, &$$,
&$1 TSRMLS_CC); }
+       |       variable_exists_variables ','   { zend_do_boolean_and_begin(&$1, &$2
TSRMLS_CC); } cvar { znode tmp; zend_do_isset_or_isempty(ZEND_ISSET,
&tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2
TSRMLS_CC); }
+;      
 
 isset_variables:
                cvar                            { zend_do_isset_or_isempty(ZEND_ISSET, 
&$$, &$1 TSRMLS_CC);
}
Index: zend_language_scanner.l
===================================================================
RCS file: /repository/Zend/zend_language_scanner.l,v
retrieving revision 1.64
diff -u -r1.64 zend_language_scanner.l
--- zend_language_scanner.l     13 Feb 2003 16:46:16 -0000      1.64
+++ zend_language_scanner.l     20 Jun 2003 11:35:23 -0000
@@ -927,6 +927,10 @@
        return T_ISSET;
 }
 
+<ST_IN_SCRIPTING>"variable_exists" {
+       return T_VARIABLE_EXISTS;
+}
+
 <ST_IN_SCRIPTING>"empty" {
        return T_EMPTY;
 }


Reproduce code:
---------------
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);

echo "<h3>Array testing</h3>";
echo "\$arr = array(1 => null, 2 => array(1 => 3, 2 => null));\n\n";
$arr = array(1 => null, 2 => array(1 => 3, 2 => null));
echo "variable_exists(\$arr[1]): " . (variable_exists($arr[1]) ? 'yes'
: 'no') . " (should be yes)\n";
echo "variable_exists(\$arr[2]): " . (variable_exists($arr[2]) ? 'yes'
: 'no') . " (should be yes)\n";
echo "variable_exists(\$arr[3]): " . (variable_exists($arr[3]) ? 'yes'
: 'no') . " (should be no)\n";
echo "variable_exists(\$arr[1][2]): " . (variable_exists($arr[1][2]) ?
'yes' : 'no') . " (should be no)\n";
echo "variable_exists(\$arr[2][1]): " . (variable_exists($arr[2][1]) ?
'yes' : 'no') . " (should be yes)\n";
echo "variable_exists(\$arr[2][2]): " . (variable_exists($arr[2][2]) ?
'yes' : 'no') . " (should be yes)\n";
echo "variable_exists(\$arr[2][3]): " . (variable_exists($arr[2][3]) ?
'yes' : 'no') . " (should be no)\n";

echo "<h3>Scalar testing</h3>";
echo "\$foo = null\n\n";
$foo = null;
echo "variable_exists(\$foo): " . (variable_exists($foo) ? 'yes' :
'no') . " (should be yes)\n";
echo "unset(\$foo);\n";
unset($foo);
echo "variable_exists(\$foo): " . (variable_exists($foo) ? 'yes' :
'no') . " (should be no)\n";
echo "variable_exists(\$bar): " . (variable_exists($bar) ? 'yes' :
'no') . " (should be no)\n";
?>

Actual result:
--------------
(Actual output from PHP 4.3.2 with the given patch):

Array testing
$arr = array(1 => null, 2 => array(1 => 3, 2 => null));

variable_exists($arr[1]): yes (should be yes)
variable_exists($arr[2]): yes (should be yes)
variable_exists($arr[3]): no (should be no)
variable_exists($arr[1][2]): no (should be no)
variable_exists($arr[2][1]): yes (should be yes)
variable_exists($arr[2][2]): yes (should be yes)
variable_exists($arr[2][3]): no (should be no)
Scalar testing
$foo = null

variable_exists($foo): yes (should be yes)
unset($foo);
variable_exists($foo): no (should be no)
variable_exists($bar): no (should be no)



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=24274&edit=1

Reply via email to