From: [EMAIL PROTECTED]
Operating system: All
PHP version: 4CVS-2003-06-20 (stable)
PHP Bug Type: Feature/Change Request
Bug description: New 'function' variable_exists(); patch included
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 bug report at http://bugs.php.net/?id=24274&edit=1
--
Try a CVS snapshot: http://bugs.php.net/fix.php?id=24274&r=trysnapshot
Fixed in CVS: http://bugs.php.net/fix.php?id=24274&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=24274&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=24274&r=needtrace
Try newer version: http://bugs.php.net/fix.php?id=24274&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=24274&r=support
Expected behavior: http://bugs.php.net/fix.php?id=24274&r=notwrong
Not enough info: http://bugs.php.net/fix.php?id=24274&r=notenoughinfo
Submitted twice: http://bugs.php.net/fix.php?id=24274&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=24274&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=24274&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=24274&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=24274&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=24274&r=gnused