benlowery.co.uk

PHP 7.1 nullable return types, Eloquent Models and Intellij - So much awesome!

One of the things added in PHP 7.1 was nullable return types (return types where added in 7 see here).

The return type tells the PHP interpreter what type the method will be returning (bit obvious from the name really).

The advantages of return types are manifold but a key one is they allow you to catch errors at development time.

Why it is useful at runtime is a topic for another post.

Any time you can get the IDE to protect you from your own mistakes you should

So what else can we make Intellij (and PhpStorm) do with return types? well how about this :-

The IDE is giving us full intellisense completion on a variable that was assigned from the result of calling createLandingPage and it knows that it's a descendant of a Laravel eloquent model and even what that models relations are!.

So now you are telling yourself you want this (..you know you are).

Setting things up.

Once you have installed those you'll need to tell ide-helper to generate a helper file for the IDE, this is the step that allows Intellij/PhpStorm to actually 'understand' your models.

In my case my models aren't in the usual place so I need to run a command similar to this :-

./artisan ide-helper:models --dir="Meta/Core/Models/"

I always say no when it asks the question of whether to rewrite your actual models or create a single helper file, I prefer the single helper file (I trust everything barryvdh puts out as his packages are incredible but something about auto-rewriting hand written code makes me shiver).

The output of the above command then looks something like this :-

<?php

namespace Meta\Core\Models{
    /**
    * Meta\Core\Models\LandingPage
    *
    * @property int $id
    * @property string $title
    * @property string $type
    * @property string $content_uuid
    // others
    * @property-read \Meta\Core\Models\ActiveLandingPage $activeLandingPage

When the IDE parses through this file it's telling it what properties etc the Model has which allows the IDE to offer proper intellisense even on relations.

So now the IDE knows how to handle the properties/relations on the model how do we indicate what the return value of a method should be treat as?

We add a nullable return type declaration :-

<?php

public function createLandingPage(array $data): ?LandingPage
{
 // some awesome code
 // that returns an instance of LandingPage or null
}

The : ?LandingPage after the method declaration (aside: PHP has some funky looking syntax doesn't it? C# uses <type>? ) basically means "must return an instance of LandingPage or null without the ? it would be saying "must return an instance of LandingPage".

And that is it.

When the IDE sees $foo = $bar->createLandingPage($someData) it knows that its getting back a LandingPage (or null) and since it knows how to handle that you get full completion.

Note: You can do this, don't do this.

Final Notes

There is a never ending debate in PHP-land about whether a method should return null or throw an exception if (for example) something isn't found that should be.

I don't really pick a side in that fight since different code bases I've worked on have done it differently and I really don't have a preference.

PHP's addition of nullable return types has made it a lot nicer on the codebases that do return null though so if that is you, it's well worth a look when you upgrade to 7.1.

Further Reading