PhpStorm PDOStatement警告

PhpStorm PDOStatement警告

问题描述:

Consider the following class:

class output_Home {
    public $app;
    public $forums;

    function __construct ($app) {
        // main app class containing db, settings, etc
        $this->app = $app;

        // populate class property arrays for use in template
        $this->setForums();
    }

    function setForums () {
        /*
         * select all forum data, dump into $this->forums array
         * fields:
         *      id, name, slug, description, order,
         *      total_threads, total_posts,
         *      last_post_id, last_post_date, last_poster_id, last_poster_username, last_poster_avatar
         */
        $sql = "select f.*,
                p.id as last_post_id, p.date_created as last_post_date,
                u.id as last_poster_id, u.username as last_poster_username, u.avatar as last_poster_avatar,
                (select count(*) from `threads` where `id_forum`=f.id) as total_threads,
                (select count(*) from `posts` where `id_forum`=f.id) as total_posts
                from `forums` as f
                left join `posts` as p on (p.id = (select `id` from `posts` where `id_forum`=f.id order by `date_created` desc limit 1))
                left join `users` as u on (u.id = p.id_user)
                order by f.order asc";
        $stm = $this->app->db->prepare($sql);
        $stm->execute();
        $this->forums = $this->app->sanitizer->action('sanitize', $stm->fetchAll());
    }
}

Here is my object_App class:

class object_App {
    public $db;

    function __construct () {
        // create database "db" connection
        $this->db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    }
}

Here is how $this->app is passed to the output_Home class:

$app = new object_App();
$home = new output_Home($app);

The $app property contains a property called db, which is a PDO object. Notice the $stm variable in particular here.

My problem is that I am getting warnings from PhpStorm claiming that methods such as $stm->execute() are not found in the class. Well of course they aren't, because they are PDOStatements.

I just want to know if there is a way I can get rid of the warnings properly, without using PHPDocs above every single $stm I make, because I will be making quite a few in several different class methods, and I don't want PHPDocs everywhere in the code.

Any help would be appreciated.

1. Provide proper type hint for $db. In your particular case this may not be 100% necessary, but better have it (it's one time job)

class object_App {
    /** @var \PDO */
    public $db;
    ...

In general IDE can figure out what $db is because you have $this->db = new PDO(...); and it's located in __construct() (2 important factors).. but it's better be on safer side with proper type hint. if such line would be placed in some ordinary method (e.g. createDBConnection() or something, IDE will not do that costly extra intelligence.

2. Most importantly -- provide type hint for your $app. The way how you are passing this argument gives no hints for IDE.

It could be done like this (and IDE should figure out the rest):

function __construct (object_App $app) {

Or better in a same way as in #1:

class output_Home {
    /** @var object_App */
    public $app;

or even better -- combine them together:

class output_Home {
    /** @var object_App */
    public $app;

    function __construct (object_App $app) {
    ...

unless PHPStorm knows what type of object a method returns, it has no way of knowing what methods might be available to that object.

you have 3 options:

1) as you stated, use a quick phpdoc to tell phpstorm what it is (you only need to do this once in a code block:

/** @var SomeObject $stm */
$stm = $this->app->db->prepare($sql);

2) supress the warning altogether

find:

settings > editor > inspections

then untick undefined method under PHP > undefined.

3) if you have control of the method being called:

make sure that you include the return type in the phpdoc for the method, PHPStorm will use that to determine what it needs.

/**
* @return SomeObject
*/
public function someFunction() {
   // some stuff
}