Edit report at https://bugs.php.net/bug.php?id=24274&edit=1
ID: 24274
Updated by: levim@php.net
Reported by: torben@php.net
Summary: New 'function' variable_exists(); patch included
-Status: Open
+Status: Feedback
Type: Feature/Change Request
-Package: Feature/Change Request
+Package: *General Issues
-Operating System: All
+Operating System: Any
-PHP Version: 4CVS-2003-06-20 (stable)
+PHP Version: *
Block user comment: N
Private report: N
New Comment:
What value is knowing if a variable exists? In the local scope you should already know what
variables exist. The only other use cases I can think of are checking array keys or object
properties and there are already functions for those. What are your current thoughts?
Previous Comments:
------------------------------------------------------------------------
[2012-05-18 14:03:38] mark at unserver dot de
Any news on this? The current solution (using array_key_exists on $GLOBALS) is quite ugly.
------------------------------------------------------------------------
[2003-08-22 12:06:47] xuefer at 21cn dot com
we have isset() and empty()
not variable_isset() nor variable_isempty()
so why variable_exists() ? why not just exists() ?
it will be widely used if it's implemented
so keep it short if possible :)
------------------------------------------------------------------------
[2003-06-22 10:10:17] cunha17 at uol dot com dot br <Cristiano Duarte>
I think it is a nice function. Are there any plans to commit it to CVS ?
------------------------------------------------------------------------
[2003-06-20 17:28:37] torben at thebuttlesschaps dot com
Hmm. A non-messed-up patch can be found here:
http://www.thebuttlesschaps.com/variable_exists_patch.txt
Torben
------------------------------------------------------------------------
[2003-06-20 17:08:17] torben@php.net
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 https://bugs.php.net/bug.php?id=24274&edit=1