在PHP中取消设置之前检查var是否存在?

Jas*_*vis 79 php

有了错误报告,甚至是最佳实践,当在PHP中取消设置变量时,你应该先检查它是否存在(在这种情况下它并不总是存在)并取消设置,或者只是取消设置它?

<?PHP
if (isset($_SESSION['signup_errors'])){
    unset($_SESSION['signup_errors']);
}

// OR

unset($_SESSION['signup_errors']);
?>
Run Code Online (Sandbox Code Playgroud)

Joã*_*lva 146

只是取消它,如果它不存在,什么都不会做.

  • @SilentGhost我同意,这似乎是一个简单的测试,但他们正在寻求专业建议,虽然错误日志可能没有任何错误/警告/通知未设置未定义的var,但可能还有其他未记录的问题.例如,调用unset意味着PHP通过ALL var数据进行调整,因为它无法找到任何内容,而使用`if set`可能会有更好的索引方案.(只是一个例子,前者可能是补鞋匠,两种方法都使用相同的数据检查方法). (17认同)
  • @jasondavis:你试过的时候发生了什么? (12认同)
  • 我不知道是否会发出警告或通知 (3认同)
  • 投票否决 - 您无法取消设置未定义的数组键。 (3认同)
  • @jascha 我说,我们不能! (2认同)

Mr.*_*ith 47

从PHP手册:

关于在这些注释中早些时候的一些混淆,关于是什么原因导致unset()在取消设置不存在的变量时触发通知....

取消不存在的变量,如

<?php
unset($undefinedVariable);
?>
Run Code Online (Sandbox Code Playgroud)

不会触发"未定义变量"通知.但

<?php
unset($undefinedArray[$undefinedKey]);
?>
Run Code Online (Sandbox Code Playgroud)

触发两个通知,因为此代码用于取消设置数组的元素; $ undefinedArray和$ undefinedKey本身都没有被设置,它们只是被用来定位应该取消的东西.毕竟,如果他们确实存在,你仍然期望他们两个都在后面.你不希望你的整个数组消失只是因为你取消了()其中一个元素!

  • 这需要更多澄清.只要数组本身存在,您就可以取消设置未定义的数组键. (40认同)

Dan*_*ray 18

unset在未定义的变量上使用不会导致任何错误(除非变量是不存在的数组(或对象)的索引).

因此,您唯一需要考虑的是最有效的方法.如我的测试所示,不使用'isset'进行测试更有效率.

测试:

function A()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($defined);
    }
}

function B()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($undefined);
    }
}

function C()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($defined))
            unset($defined);
    }
}

function D()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($undefined))
            unset($undefined);
    }
}

$time_pre = microtime(true);
A();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function A time = $exec_time ";

$time_pre = microtime(true);
B();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function B time = $exec_time ";

$time_pre = microtime(true);
C();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function C time = $exec_time ";

$time_pre = microtime(true);
D();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function D time = $exec_time";
exit();
Run Code Online (Sandbox Code Playgroud)

结果:

  1. Function A time = 1.0307259559631
    • 定义没有isset
  2. Function B time = 0.72514510154724
    • 未定义的未定义
  3. Function C time = 1.3804969787598
    • 使用isset定义
  4. Function D time = 0.86475610733032
    • 使用isset未定义

结论:

它的使用效率始终较低isset,更不用说写入所需的少量额外时间.尝试unset一个未定义的变量比检查它是否可以更快unset.

  • 这比接受的答案要好得多!感谢您运行这些测试。 (3认同)

Tar*_*nes 6

如果你想取消设置一个变量,那么你可以使用unset

unset($any_variable); // bool, object, int, string etc
Run Code Online (Sandbox Code Playgroud)

当尝试取消设置变量时,检查其是否存在没有任何好处。

如果变量是一个数组并且您希望取消设置一个元素,则必须首先确保父元素存在,这也适用于对象属性。

unset($undefined_array['undefined_element_key']); // error - Undefined variable: undefined_array

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object
Run Code Online (Sandbox Code Playgroud)

通过将 包装unset在一个if(isset($var)){ ... }块中可以轻松解决这个问题。

if(isset($undefined_array)){
    unset($undefined_array['undefined_element_key']); 
}

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}
Run Code Online (Sandbox Code Playgroud)

我们只检查变量(parent)的原因很简单,因为我们不需要检查属性/元素,这样做会导致编写和计算速度慢很多,因为它会添加额外的检查。

if(isset($array)){
...
}

if(isset($object)){
...
}
Run Code Online (Sandbox Code Playgroud)

.vs

$object->prop_name = null;
$array['element_key'] = null;

// This way elements/properties with the value of `null` can still be unset.

if(isset($array) && array_key_exists('element_key', $array)){
...
}

if(isset($object) && property_exists($object, 'prop_name')){
...
}

// or 

// This way elements/properties with `null` values wont be unset.

if(isset($array) && $array['element_key'])){
...
}

if(isset($object) && $object->prop_name)){
...
}
Run Code Online (Sandbox Code Playgroud)

type这是不言而喻的,但在获取、设置和取消设置元素或属性时了解变量的含义也很重要;使用错误的语法将引发错误。

尝试取消设置多维数组或对象的值时也是如此。您必须确保父键/名称存在。

if(isset($variable['undefined_key'])){
    unset($variable['undefined_key']['another_undefined_key']);
}

if(isset($variable->undefined_prop)){
    unset($variable->undefined_prop->another_undefined_prop);
}
Run Code Online (Sandbox Code Playgroud)

在处理对象时,还有另一件事需要考虑,那就是可见性。

它存在并不意味着您有权修改它。