admin管理员组

文章数量:1391956

I am initializing a class where the constructor requires a WP_Post object. The object I would like to pass comes from get_queried_object() which could return almost anything. I am using is_a() to make sure I have the right type, which "works", but my IDE does not recognize that I have constrained the type.

Is there a way to make it clear to the IDE that I have done my due diligence? I don't want to get in the habit of ignoring my IDE. It has been so nice to me in the past and saved me from so many mistakes. :)

$queried_object = get_queried_object();

if ( is_singular() && is_a( $queried_object, 'WP_Post' ) ) {
    // Initialize class that requires WP_Post object.
    $class = new ClassThatOnlyAcceptsPostObject( $queried_object );

    // ...
}

I am initializing a class where the constructor requires a WP_Post object. The object I would like to pass comes from get_queried_object() which could return almost anything. I am using is_a() to make sure I have the right type, which "works", but my IDE does not recognize that I have constrained the type.

Is there a way to make it clear to the IDE that I have done my due diligence? I don't want to get in the habit of ignoring my IDE. It has been so nice to me in the past and saved me from so many mistakes. :)

$queried_object = get_queried_object();

if ( is_singular() && is_a( $queried_object, 'WP_Post' ) ) {
    // Initialize class that requires WP_Post object.
    $class = new ClassThatOnlyAcceptsPostObject( $queried_object );

    // ...
}
Share Improve this question edited Feb 27, 2020 at 12:59 Luke Gedeon asked Feb 26, 2020 at 16:19 Luke GedeonLuke Gedeon 2101 silver badge16 bronze badges 2
  • If is_singular() is true, then the queried object must be a post object. – Jacob Peattie Commented Feb 27, 2020 at 0:55
  • Thanks @JacobPeattie that is a good point, however my IDE is not so easily convinced. It doesn't even trust is_a(). Thankfully it does trust instanceof. – Luke Gedeon Commented Feb 27, 2020 at 13:05
Add a comment  | 

2 Answers 2

Reset to default 2

In addition to what Tom already said, using instanceof has worked quite well for me. (Actually never heard of is_a() before.)

if (is_singular() && $queried_object instanceof \WP_Post) {
    // do something
}

Both PHPStan and my IDE know that after this check, $queried_object is an instance of the WP_Post class.

No, you can't change what a function returns without modifying it.

You can, however, do several other things:

  • Provide type hints on your constructor's arguments, your IDE and PHP will then know that a \WP_Post object is required and that nothing else will do
  • Use instanceof instead of is_a, which will be picked up by the IDE
  • Perform checks on the return values of the functions and handle their failures
  • Convert non-post object return values into something the class will accept
  • Refactor things so that you never end up in the situation where a WP_Term or some other kind of object is returned
  • Wrap the function in another function that returns either a post or an error value if it's not a post/valid

More importantly, I have to question the value of an object named PostContent, and whether it's using classes for the sake of using classes. I don't see what the object can do to a posts content that can't be achieved using standard templates and filters on the_content. By rolling your own, you give up a lot of the advantages, filters, and plugin compatibility you get by just using standard APIs and a standard post loop. If this classes job is to process markdown or insert ads, then it needs a more specific name, and can just be created as and when it's needed

本文标签: phpIs there a way to enforce the type of an object returned by a function that could return anything