【问题标题】:Check if var exist before unsetting in PHP?在 PHP 中取消设置之前检查 var 是否存在?
【发布时间】:2021-06-17 16:38:19
【问题描述】:

启用错误报告,甚至最佳实践,在 PHP 中取消设置变量时,您应该先检查它是否存在(在这种情况下,它并不总是存在)然后取消设置,还是直接取消设置?

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

// OR

unset($_SESSION['signup_errors']);
?>

【问题讨论】:

  • NOT使用isset效率更高。看看我的回答。我已经进行了测试以找出速度差异。

标签: php


【解决方案1】:

只要取消设置,如果不存在,什么都不做。

【讨论】:

  • 我不知道它是否会引发警告或通知
  • @SilentGhost 我同意,这似乎是一个简单的测试,但他们正在寻求专业建议,虽然错误日志可能没有任何错误/警告/通知取消设置未定义的 var,但可能有其他未记录的问题。例如只是调用 unset 意味着 PHP 遍历所有 var 数据,因为它找不到任何东西,而使用 if set 可能有一些更好的索引方案。 (只是一个例子,前面的可能是 cobblers 并且两种方法使用相同的数据检查方法)。
  • 投反对票 - 您不能取消设置未定义的数组键。
  • 这不对,@Behnam。您不能取消设置“未定义数组”的数组键。看看 TarranJones 的回答
  • @jascha 我说,我们不能!
【解决方案2】:

From the PHP Manual:

关于前面的一些混淆 这些关于导致 unset() 的原因的注释 取消设置时触发通知 不存在的变量......

取消设置不存在的变量, 如

<?php
unset($undefinedVariable);
?>

不会触发“未定义 变量”通知。但是

<?php
unset($undefinedArray[$undefinedKey]);
?>

触发两个通知,因为这 代码用于取消设置 大批;既不是 $undefinedArray 也不是 $undefinedKey 本身就是 未设置,他们只是习惯于 找到应该取消设置的内容。后 所有,如果它们确实存在,你仍然会 希望他们都在身边 然后。你不会想要你的 整个数组消失只是因为 你 unset() 它的元素之一!

【讨论】:

  • 这需要进一步澄清。只要数组本身存在,您就可以取消设置未定义的数组键。
  • @kristovaher 确实 - 这根本没有解决 OP 描述的特定场景。
【解决方案3】:

在未定义的变量上使用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();

结果:

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

结论:

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

【讨论】:

  • 这比公认的答案要好得多!感谢您运行这些测试。
  • 你不是在测试类似的东西。内存分配比内存分配更昂贵,这就是为什么 A 和 C 需要更长的时间。最好只考虑幕后必须发生的事情。 php 不可能在不知道是否已设置的情况下取消设置某些内容,因此它必须在内部调用 isset。因此,自行调用 unset 总是会更快。
【解决方案4】:

如果您想取消设置变量,则可以使用 unset

unset($any_variable); // bool, object, int, string etc

在尝试取消设置变量时检查它的存在没有任何好处。

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

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

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object

这很容易通过将unset 包装在if(isset($var)){ ... } 块中来解决。

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

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}

我们只检查变量(parent)的原因仅仅是因为我们不需要检查属性/元素,这样做会增加编写和计算的速度额外检查。

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

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

.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)){
...
}

这是不言而喻的,但在获取、设置和取消设置元素或属性时知道变量的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);
}

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

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

【讨论】:

  • 终于,一个正确的答案。谢谢。
  • 一个小更新:在 PHP 7.4/8.0 中,当您 unset 不存在的父对象的属性时不会引发错误。但是,在 PHP8 中取消不存在数组中的键不仅会引发通知,还会引发警告(可能会更改)。
【解决方案5】:

检查此链接 https://3v4l.org/hPAto

在线工具显示不同版本PHP的代码兼容性

根据这个工具的代码

unset($_SESSION['signup_errors']);

适用于 PHP >=5.4.0,不会给您任何通知/警告/错误。

【讨论】:

    猜你喜欢
    • 2019-07-23
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2020-11-16
    • 1970-01-01
    • 2012-01-10
    相关资源
    最近更新 更多