今天在工作中,我陷入了一系列无法理解的代码。 我在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表达式和语句的关键提示。
建议:我不想通过制作一个“构造良好”的循环来修复我的代码 - 解决方案很明显 - 我很想知道这里发生了什么。非常感谢所有帮助。
答案 0 :(得分: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;
}
已经发生了。这是一个快速修复:
{{1}}
另外,PHP有一个名为uniqid()的便捷函数,可以为你做类似的事情。它每次都会给你一个独特的字符串。
答案 1 :(得分:1)
PHP需要首先评估赋值,然后才能进行比较。通常,赋值运算符的优先级非常低,因此在编写$a = $b + $c
时,首先计算加法,然后将结果分配给$ a。
但是,这是一个特殊情况,虽然它似乎没有很好地记录,但在文档中可以找到类似的情况,说明:
虽然
=
的优先级低于大多数其他运算符,但PHP会 仍允许使用类似于以下内容的表达式:if (!$a = foo())
,in 在哪种情况下,foo()
的返回值会被放入$a
。
因此,在这种情况下,PHP确定它需要先执行赋值,然后才能否定赋值的结果。我认为这里发生了类似的事情,尽管你应该能够在以后做PHP。
实际上,结果可能是不可预测的,就像其他一些表达式一样:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5