Ответ 1
IIRC, вы можете использовать get_defined_vars()
для этого:
$foo = NULL;
$vars = get_defined_vars();
if (array_key_exists('bar', $vars)) {}; // Should evaluate to FALSE
if (array_key_exists('foo', $vars)) {}; // Should evaluate to TRUE
Мне нужно проверить, определено ли значение как что-либо, включая null. isset
обрабатывает нулевые значения как undefined и возвращает false
. В качестве примера возьмем следующее:
$foo = null;
if(isset($foo)) // returns false
if(isset($bar)) // returns false
if(isset($foo) || is_null($foo)) // returns true
if(isset($bar) || is_null($bar)) // returns true, raises a notice
Обратите внимание, что $bar
- undefined.
Мне нужно найти условие, которое удовлетворяет следующему:
if(something($bar)) // returns false;
if(something($foo)) // returns true;
Любые идеи?
IIRC, вы можете использовать get_defined_vars()
для этого:
$foo = NULL;
$vars = get_defined_vars();
if (array_key_exists('bar', $vars)) {}; // Should evaluate to FALSE
if (array_key_exists('foo', $vars)) {}; // Should evaluate to TRUE
Если вы имеете дело с свойствами объекта, у которых может быть значение NULL, вы можете использовать: property_exists()
вместо isset()
<?php
class myClass {
public $mine;
private $xpto;
static protected $test;
function test() {
var_dump(property_exists($this, 'xpto')); //true
}
}
var_dump(property_exists('myClass', 'mine')); //true
var_dump(property_exists(new myClass, 'mine')); //true
var_dump(property_exists('myClass', 'xpto')); //true, as of PHP 5.3.0
var_dump(property_exists('myClass', 'bar')); //false
var_dump(property_exists('myClass', 'test')); //true, as of PHP 5.3.0
myClass::test();
?>
В противоположность isset() свойство_exists() возвращает TRUE, даже если свойство имеет значение NULL.
См. Лучший способ проверить существование переменной в PHP; isset() явно нарушен
if( array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true
if( array_key_exists('bar', $GLOBALS) && is_null($bar)) // false & => false
Я обнаружил, что compact
- это функция, которая игнорирует неустановленные переменные, но действует на те, которые установлены на null
, поэтому, когда у вас есть большая таблица локальных символов, я бы предположил, что вы можете получить более эффективное решение при проверке array_key_exists('foo', get_defined_vars())
с помощью array_key_exists('foo', compact('foo'))
:
$foo = null;
echo isset($foo) ? 'true' : 'false'; // false
echo array_key_exists('foo', compact('foo')) ? 'true' : 'false'; // true
echo isset($bar) ? 'true' : 'false'; // false
echo array_key_exists('bar', compact('bar')) ? 'true' : 'false'; // false
Следующий код, написанный как расширение PHP, эквивалентен array_key_exists ($ name, get_defined_vars()) (спасибо Henrik и Hannes).
// get_defined_vars()
// https://github.com/php/php-src/blob/master/Zend/zend_builtin_functions.c#L1777
// array_key_exists
// https://github.com/php/php-src/blob/master/ext/standard/array.c#L4393
PHP_FUNCTION(is_defined_var)
{
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
return;
}
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
if (zend_symtable_exists(EG(active_symbol_table), name, name_len + 1)) {
RETURN_TRUE;
}
}
Вы можете использовать is_null и empty вместо of isset(). Empty не выводит сообщение об ошибке, если переменная не существует.
Вот некоторые глупые обходные пути с использованием xdebug.; -)
function is_declared($name) {
ob_start();
xdebug_debug_zval($name);
$content = ob_get_clean();
return !empty($content);
}
$foo = null;
var_dump(is_declared('foo')); // -> true
$bla = 'bla';
var_dump(is_declared('bla')); // -> true
var_dump(is_declared('bar')); // -> false
is_null($bar)
возвращает true, так как он вообще не имеет значений. Кроме того, вы можете использовать:
if(isset($bar) && is_null($bar)) // returns false
чтобы проверить, существует ли $bar
, и будет возвращать только true, если:
$bar = null;
if(isset($bar) && is_null($bar)) // returns true