我正在尝试使用
usort()
并在其函数范围内利用全局变量,但没有成功。
我已将代码简化为简单的框架来展示我的意思:
$testglobal = 1;
function cmp($a, $b) {
global $testglobal;
echo 'hi' . $testglobal;
}
usort($topics, "cmp");
假设
usort()
运行两次,我的期望是输出:
hi1hi1
相反,我的输出是:
hihi
我已阅读手册(http://us.php.net/usort),我没有看到访问全局变量有任何限制。如果我将
usort()
分配给我回显的变量,它会输出 1,因此 usort()
肯定运行成功(另外,还有所有这些“hi”)。
无法重现“错误”,键盘也无法重现:http://codepad.org/5kwctnDP
您还可以使用对象属性代替全局变量
<?php
class Foo {
protected $test = 1;
public function bar($a, $b) {
echo 'hi' . $this->test;
return strcmp($a, $b);
}
}
$topics = array(1,2,3);
$foo = new Foo;
usort($topics, array($foo, 'bar'));
我在问题中输入的代码被放入 bbPress 的模板中,bbPress 是 WordPress 的近亲论坛。一位朋友告诉我,“有时,如果您在定义变量之前没有全局变量,PHP 会表现得很奇怪,具体取决于代码执行时的嵌套程度 - bbPress 在模板输出时会执行一些复杂的包含操作”。
所以我尝试了一下,它有效:
global $hi123;
$hi123 = ' working ';
我正在回答我自己的问题,以防像我这样的另一个白痴在谷歌搜索中发现这个。 :-)
不过,我将接受 VolkerK 的回答,因为对象解决方法非常聪明。
$GLOBALS
数组访问变量是否有效?
$testglobal = 1;
function cmp($a, $b) {
echo 'hi' . $GLOBALS['testglobal'];
}
usort($topics, "cmp");
它从 php 5.2.4 开始工作
$testglobal = ' WORKING ';
$topics = array('a','b','c');
function cmp($a, $b) {
global $testglobal;
echo 'hi' . $testglobal;
}
usort($topics, "cmp");
// hi WORKING hi WORKING
不要将变量定义为
global
或访问 $GLOBALS
作为解决方法 - 这些是现代应用程序中的代码味道,并且通常会恶化变量的范围控制。
对于 PHP7.4 以下的应用程序(并且在 2023 年,您不应该使用过时的版本),您可以通过函数签名后的
use ($theGlobalVariable)
允许访问全局变量。
对于使用 PHP7.4 或更高版本的应用程序,“箭头函数语法”允许在函数作用域内读取全局变量。
这里演示了如何在
usort()
调用内部利用全局范围的查找数组。这是一个非常实用的示例,常见于专业代码库中,用于执行自定义排序。
代码:(演示)
$lookup = [
'foo' => 1,
'bar' => 2,
'baz' => 3,
'fizz' => 4,
'buzz' => 5,
];
$array = ['buzz', 'foo', 'baz'];
// sort $array ascending according to its mapped value
usort($array, fn($a, $b) => $lookup[$a] <=> $lookup[$b]);
var_export($array);
输出:
array (
0 => 'foo',
1 => 'baz',
2 => 'buzz',
)