使用example.php:
$args = __FILE__.' -vvv';
$argv = explode(' ', $args);
$argc = count($argv);
$GLOBALS['argv'] = $_SERVER['argv'] = $argv;
$GLOBALS['argc'] = $_SERVER['argc'] = $argc;
var_export(getopt('v'));
$ example.php -v
>数组(' v' => false);
最终getopt
无法通过$GLOBALS
获取argv
。那么我有什么方法可以覆盖argv
数组?
答案 0 :(得分:12)
不,没有本地方法可以做到这一点。根据您的目标,可能有其他方法可以解决问题,但覆盖不是其中之一。
<强>结构强>
要明白为什么会这样,你应该知道,超级全局变量不仅仅是你所指的“变量”。这意味着,如果您使用$argv
取消引用参数列表,不意味着您将访问一些存储在<变量中的数据 $argv
。相反,您将通过名为$argv
的“链接”访问数据容器。但是,有多种方法可以访问此数据 - 至少$_SERVER['argv']
或$GLOBALS
数组。为了说明,我将使用代码:
var_dump($argv, $_SERVER['argv']);
unset($argv);
var_dump($argv, $_SERVER['argv']);
这将导致类似:
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- derived from $argv
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- derived from $_SERVER['argv']
NULL//<------------------ we've unset $argv, so unset a reference
array(2) {
[0]=>
string(11) "example.php"
[1]=>
string(4) "-vvv"
}//<--------------------- but data is still there and available via another reference
<强>内部强>
如您所见,可以销毁引用,但实际数据将保持不变。这将存储在symbols table中。许多PHP函数正在访问此结构以检索数据,getopt()
也不例外。所以结论是 - 是的,你可以修改引用(甚至破坏它),但实际数据仍然是超级全局数据。
getopt()
现在,关于这个功能。只需看一下implementation:
/* Get argv from the global symbol table. We calculate argc ourselves
* in order to be on the safe side, even though it is also available
* from the symbol table. */
if (PG(http_globals)[TRACK_VARS_SERVER] &&
(zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE ||
zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) && Z_TYPE_PP(args) == IS_ARRAY
)
{
//...omitted
}
明确指出,它会尝试在"argv"
中搜索symbol_table
(如果您需要 - 这里是指向 - how的链接,它将完全完成)。这意味着 - 它将访问实际数据,因此,从外部覆盖它将不起作用。
结果 - getopt()
将处理在脚本启动时收集的数据,并且该数据将包含实际参数,无论您是否在脚本中覆盖它们。