请比较以下代码:
1)
/file.php:
    $newconn = new PDO('mysql:host=localhost;charset=utf8mb4;','username','password');
2)
../secrets.php:
    $mysqlusername = 'username';
    $mysqlpassword = 'password';
/file.php:
    require_once('../secrets.php');
    $newconn = new PDO('mysql:host=localhost;charset=utf8mb4;',$mysqlusername,$mysqlpassword);
3
../secrets.php:
    function pdoconn(i) {
        $mysqlusername = ['username1','username2'];
        $mysqlpassword = ['password1','password2'];
        $conn = new PDO('mysql:host=localhost;charset=utf8mb4;',$mysqlusername[i],$mysqlpassword[i]);
        return $conn;
    }
/file.php:
    require_once('../secrets.php');
    $newconn = pdoconn(0);
示例 1 是不可能的 - 生产服务器上的错误配置最终可能会向非预期方显示敏感参数。
示例 2 更好,但这些变量在整个应用程序中都可用,并且可以修改,这可能会导致错误。
示例 3 使事情变得非常有条理和可转移。
如果../secrets.php改为使用全局变量,则可以修改为:
../secrets.php:
$mysqlusername = 'username';
$mysqlpassword = 'password';
function pdoconn()  {
    $conn = new
PDO('mysql:host=localhost;charset=utf8mb4;',$GLOBALS['mysqlusername'],$GLOBALS['mysqlpassword']);
return $conn;
}
我认为这以非常简洁的方式说明了为什么大多数时候全局没有意义。
概括:
至于使用全局变量的安全漏洞(以及为什么我在 PHP 中编写这些示例),在 PHP 4.2.0中有一个(当时)有争议的更改,其中 register_globals 被打开到关闭。我现在找不到任何文章,因为此更改是在 2002 年进行的,但我似乎确实记得它对当时的一些违规行为负责。直接从手册中复制,有一个非常清晰的易受攻击代码示例:
<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
    $authorized = true;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
    include "/highly/sensitive/data.php";
}
?>