3

今天在工作中,我被困在一行我无法理解的代码中。我在 JavaScript 中有一个函数,为了确保获得唯一的时间戳,我做了那个丑陋的循环:

var ts = +new Date();
while (ts === (ts = +new Date()));

我认为很清楚我们正在重新设置 ts 直到它的值变得不同。

但是当我尝试将函数迁移到 PHP 代码时 - 就像这样:

$ts = preg_replace('/^\d\.(\d+)\s(\d+)$/', '$2$1', microtime());
//regex extracts digits and re-positions them - ugly microtime :(
while ($ts === ($ts = preg_replace('/^\d\.(\d+)\s(\d+)$/', '$2$1', microtime())));

解释器进入无限循环。我所有的尝试似乎都表明 $ts 分配是在比较之前进行的,但我不明白为什么没有首先解决左侧表达式。我的 PHP 知识没有我的 JavaScript 知识那么大,所以我想知道是否有一些关于我泄露的 PHP 表达式和语句的关键提示。

建议:我不想通过制作“结构良好”的循环来修复我的代码——解决方案很明显——我很想了解这里发生了什么。非常感谢所有帮助。

4

2 回答 2

1

PHP 将在比较之前评估赋值,所以到它做的时候$ts ===$ts =已经发生了。这是一个快速修复:

$ts = preg_replace('/^\d\.(\d+)\s(\d+)$/', '$2$1', microtime());

//regex extracts digits and re-positions them - ugly microtime :(
while ($ts === ($ts2 = preg_replace('/^\d\.(\d+)\s(\d+)$/', '$2$1', microtime()))) {
    $ts = $ts2;
}

此外,PHP 有一个方便的函数,称为 uniqid(),它会为您做类似的事情。它每次都会给你一个唯一的字符串。

于 2012-11-21T22:41:47.553 回答
1

PHP 需要先评估赋值,然后才能进行比较。通常,赋值运算符的优先级很低,所以当你写 时$a = $b + $c,首先计算加法,然后将结果分配给 $a。然而,这是一个特例,虽然它似乎没有很好地记录在案,但在文档中发现了一个类似的案例,说明:

尽管=优先级低于大多数其他运算符,但 PHP 仍然允许类似于以下的表达式:if (!$a = foo()),在这种情况下, 的返回值foo()被放入$a

所以在这种情况下,PHP 确定它需要先进行赋值,然后才能否定赋值的结果。我认为这里正在发生类似的事情,尽管 PHP 以后应该能够完成分配是对的。

实际上,结果可能是不可预测的,就像其他一些表达式一样:

// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
于 2012-11-21T22:52:46.647 回答