Slim Framework - PDO 对象已创建但似乎不在范围内

Slim Framework - PDO object created but seems not inside the scope

我在尝试测试我的代码时遇到此错误。

Call to a member function prepare() on a non-object in ........

下面是我的代码:

ConnectionStrings.php

<?php
    $config = require dirname(__FILE__).'../../Configs/Local.php'; 

    $host = '127.0.0.1';
    $db   = 'CWW_SecurityDB';
    $user = $config['db']['user'];
    $pass = $config['db']['password'];
    $charset = 'utf8';

    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
    $opt = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];

    $pdo = new PDO($dsn, $user, $pass, $opt);

?>

Authentication.php (Related part)

<?php
    use \Psr\Http\Message\ServerRequestInterface as Request;
    use \Psr\Http\Message\ResponseInterface as Response;

    require dirname(__FILE__).'../../../ConnectionStrings.php';

    $app -> group('/authentication', function(){
        $this ->  Get('/login',
        function($request, $response, $args)
        {
            $Username = $request->getQueryParams()['Username'];
            $Password = $request->getQueryParams()['Password'];

            $sql = 'CALL SEC.usp_GetSecurityUsers(:Username)';
            $stmt = $pdo -> prepare($sql);
            $stmt -> bindParam(':Username', $Username, PDO::PARAM_STR);
            $stmt -> execute();
            .
            .
            . (just a try out on the codes)

问题应该出在行$stmt = $pdo -> prepare($sql);。但是,下班后我真的想不通。我读过其他一些有类似问题的帖子,提示 $pdo 超出范围。但是在这种情况下,我的 $pdo 究竟是如何超出范围的?有人可以赐教吗。提前谢谢你们:)

在 PHP 中,函数范围内没有自动可用的全局变量(更多信息请参见 variable scope)。在函数内部,需要定义 $pdo 或以某种方式使其可用。我想到了几种方法:

  • 在函数启动中使用 global $pdo; - 非常老派,通常不会被 php 专业人士首选。
  • $GLOBALS['pdo'] 替换 $pdo - 几乎是同一件事,有点 PHP3 风格 :)
  • 将 $pdo 传递给闭包的作用域:

      $app->group('/authentication', function() use ($pdo) {
          $this->Get('/login', function($request, $response, $args) use ($pdo) {
    
  • 通过依赖容器获取 $pdo(Slim3 为此使用 Pimple):

      // Store $pdo in DI container.
      $container = $app->getContainer();
      $container['database'] = $pdo;
      ...
      // Then inside route controller:
      $pdo = $this->get('database');