我如何在 SLIM Framework 中定义 PDO,以便 PhpStorm 不会抛出 'method not found in class' 警告?

How can I define PDO in SLIM Framework so that PhpStorm doesn't throw 'method not found in class' warnings?

所以我使用这个将 PDO 插入我的 SLIM 中:

$container['dbh'] = function($container) {
    $config = $container->get('settings')['pdo'];
    $dsn = "{$config['engine']}:host={$config['host']};dbname={$config['database']};charset={$config['charset']}";
    $username = $config['username'];
    $password = $config['password'];

    return new PDO($dsn, $username, $password, $config['options']);
};

但是,每次我使用 $this->dbh->execute()(或其他一些 PDO 方法)时,PhpStorm 都会警告我 method 'execute' not found in class

实际上这并没有什么不同,但我希望我的 PhpStorm 停止警告我它不需要的事情。

如果 PhpStorm 在识别 variable/object 时遇到问题,例如,它会发出警告 'Method some_method not found in...',例如:

$my_object->some_method();

然后你可以通过在注释中添加变量类型定义来帮助 PhpStorm 识别 class:

/**
 * @var \Some\Class $my_object
 */
$my_object->some_method();

一般例子。在使用 $my_object 变量之前添加此注释(例如,在方法开始时您将使用变量 $my_object,或者在首次使用该变量之前):

/**
 * @var \Some\Class $my_object
 */

现在每次您将在方法中使用此变量时,PhpStorm 都会知道此变量是 \Some\Class 的实例,因此对于此变量的每次使用,警告都会在以下行中消失。例如,此类用法不会显示警告:

/**
 * @var \Some\Class $my_object
 */
...
$my_object->some_method();
... 
$my_object->some_method1();
...
$my_object->some_method2();
...
$my_object->some_method();

这主要是对@rickdenhaan 评论的补充。

我注意到您正在使用 $this,这意味着您在某处有一个 class。

您可以在 class 中键入提示 dynamic/fake 属性,如下所示:

/**
 * @property PDO $dbh
 */
class MyApp {
}

如需更多帮助,请阅读 PHPDoc 文档,例如 here


在某些情况下,您可能无法影响正在实例化的原始 class。在那种情况下,您可以有一个存根文件;基本上 class 仅用于类型提示:

// Let's assume you cannot modify this class.
class App {}

// This is the stub class, we declare it as abstract to avoid instantiation by mistake.
// We make it extend `App` to get metadata from there.
abstract class AppStub extends App {
    /** @var PDO */
    public $dbh;
}


// ...later on in your code..
/** @var AppStub $this */

// tada!
$this->dbh->execute();

控制器classes方法

您的主要应用 + 路由:

$app = new \Slim\App();
$app->get('/', \YourController::class . ':home');
$app->get('/contact', \YourController::class . ':contact');

还有你的控制器:

class YourController 
{
   protected $container;

   // constructor receives container instance
   public function __construct(ContainerInterface $container) {
       $this->container = $container;
   }

   public function home($request, $response, $args) {
        $this->getDb()->execute();   // no IDE errors anymore!
        return $response;
   }

   public function contact($request, $response, $args) {
        return $response;
   }

   /**
    * @return PDO
    */
   protected function getDb()
   {
       return $this->container->get('dbh');
   }
}

如果您的 class 在命名空间中,您应该使用 \PDO 表示您指的是根命名空间中的 class。