8

执行以下操作之一是否更好?如果不是,其中一个是否比另一个快?

unset($variable);

或做

$variable = '';
4

6 回答 6

11

他们会做一些稍微不同的事情:

  • unset 将从符号表中删除变量,并将内容的引用计数减 1。之后对变量的引用将触发通知(“未定义变量”)。(注意,对象可以通过实现 __unset() 覆盖其属性的默认未设置行为)。

  • 设置为空字符串会将内容的引用计数减 1,将内容设置为长度为 0 的字符串,但符号仍将保留在符号表中,您仍然可以引用变量。(注意,对象可以通过实现 __set() 覆盖其属性的默认赋值行为)。

在较旧的 php 中,当引用计数降至 0 时,将调用析构函数并立即释放内存。在较新的版本(>= 5.3)中,php 使用缓冲方案,可以更好地处理循环引用(http://www.php.net/manual/en/features.gc.collecting-cycles.php),所以内存以后可能会被释放,但它可能根本不会被延迟......无论如何,这并不会真正导致任何问题,并且新算法可以防止某些内存泄漏。

如果变量名不再被使用, unset 应该快几个 cpu 周期(因为不需要创建新内容)。但是如果变量名被重复使用,php 将不得不创建一个新的变量和符号表条目,所以它可能会更慢!在大多数情况下,差异将是微不足道的差异。

如果要将变量标记为无效以供以后检查,可以将其设置为 false 或 null。这会比使用 isset() 测试更好,因为变量名中的拼写错误会返回 false 而不会出现任何错误...您还可以将 false 和 null 值传递给另一个函数并保留标记值,这是无法做到的一个未设置的变量...

所以我会说:

$var = false; ...
if ($var !== false) ...

或者

$var = null; ...
if (!is_null($var)) ...

比检查哨兵值更好

unset($var); ...
if (isset($var)) ...
于 2010-01-11T04:16:32.287 回答
2

从技术上讲$test = '',将返回 true

if(isset($test))

因为它仍然是“设置”,所以它只是设置为空值。

然而,它会返回 true 到

if(empty($test))

因为它是一个空变量。这仅取决于您要检查的内容。通常,人们倾向于检查变量是否为 isset,而不是它是否为空。

所以最好完全取消它。

此外,这更容易理解

unset($test);

比这个

$test = '';

第一个立即告诉您该变量不再设置。后者只是告诉您它被设置为空白区域。这通常在您要向变量添加内容并且不希望 PHP 出错时使用。

于 2010-01-11T04:16:55.923 回答
2

您正在做不同的事情,目的unset是在您创建它的上下文中销毁指定的变量,您的第二个示例只是将变量设置为空字符串。

取消设置变量不会强制立即释放内存,如果您担心性能,将变量设置为NULL可能是更好的选择,但实际上,差异不会明显......

讨论过docs

unset() 就像它的名字所说的那样 - 取消设置一个变量。它不会强制立即释放内存。PHP 的垃圾收集器会在它认为合适的时候执行它 - 有意尽快,因为无论如何都不需要这些 CPU 周期,或者直到脚本耗尽内存之前,无论首先发生什么。

如果你正在做 $whatever = null; 那么你正在重写变量的数据。您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取 CPU 周期,从而导致更长的整体执行时间。

于 2010-01-11T04:17:44.433 回答
2

我认为最相关的区别是取消设置变量表明该变量不会被后续代码使用(如果您尝试使用它,它还会通过报告 E_NOTICE 来“强制”这一点,正如 jspcal 所说,这是因为它不在符号中表了)。

因此,如果空字符串是您对变量所做的任何事情的合法(或标记)值,请继续并将其设置为 ''。否则,如果变量不再有用,取消设置它会使代码意图更清晰。

于 2010-01-11T04:19:18.307 回答
0

它们有完全不同的含义。前者使变量不存在。后者只是将其值设置为空字符串。可以说哪个“更好”并不重要,因为它们用于完全不同的事物。

你是想清理内存还是什么?如果是这样,不要;PHP 为您管理内存,因此您可以随意放置它,它会自动清理。

如果您不想清理内存,那么您需要弄清楚为什么要取消设置变量或将其设置为空,然后选择合适的变量。对此进行一项良好的健全性检查:假设有人在您的未设置/清空之后的某处插入了以下代码行:

if(strcmp($variable, '') == 0) { do_something(); }

然后,稍后:

if(!isset($variable)) { do_something_else(); }

do_something()如果您将变量设置为空字符串,第一个将运行。do_something_else()如果您取消设置变量,第二个将运行。如果您的脚本运行正常,您希望运行其中哪些?

于 2010-01-11T04:19:06.757 回答
0

这里还有一个要考虑的“问题”,即参考。

如果你有:

$a = 'foobar';
$variable =& $a;

那么做你的两个选择中的任何一个都是完全不同的。

$variable = '';

将 $variable 和 $a 都设置为空字符串,其中

unset($variable);

删除 $a 和 $variable 之间的引用链接,同时从符号表中删除 $variable。这确实是在不设置 $variable 引用其他内容的情况下取消链接 $a 和 $variable 的唯一方法。注意,例如,$variable = null; 不会的。

于 2010-01-11T05:16:16.113 回答