Hi,

I recall describing how Laravel facades work before, but not sure where it went. I thought I do it again here.

    1. app() and resolve() are just different name but the same function
    2. app(DoSomething::class) - instantiate and returns DoSomething, equivalent to new DoSomething(), PHPTools is handling this incorrectly today, the underlined secret will show call to unknown method.


      Facade classes work by returning just a key, e.g. payment/paypal, which app() will use to look up for a match in its registration list and return an instance of the class. Facade registration usually occurs inside the register() class of ServiceProviders. An example would be:

              $this->app->singleton('payment/paypal', function ($app) {
                  return new PayPal();
              });

      This is currently a hit and miss, referring to screenshots, PHPTools was able to identify the source of PayPal:: but not License::

        phptools yes, we are "guessing" facades from the register method. If it's not clear, what type it returns, we don't recognize it at all.

        This mechanism should provide good-enough IntelliSense for developers not using ide-helper or .phpstorm.meta. ...

        Anyways; we'll work on it, any feedback appreciated so we can make it better.

        JakubMisek

        Thanks! I just found what PHP Tools can't parse, it is common to write as follows too:

        $this->app->singleton('payment/paypal', function ($app) {
            return app(Payment\PayPal::class); // this is supposed to work too
        });

        JakubMisek

        After some thought, it might be a good idea to make the language server understand:

        app(PayPal::class) will return an instance of PayPal
        app(Format::class) will return an instance of Format
        likewise for resolve(...)

        To prevent wrong behavior with other PHP frameworks, this could be a configurable Laravel setting.

        phptools you're right. We have relied on ide-helper and generated phpstorm meta actually, but it's a good idea to support those cases out-of-the-box. We already handle most of the Laravel/Facade/Services cases anyways.

          2 months later

          Hi, possible?

          Otherwise my code looks very ugly like this

          $paypal = app(PayPal::class);
          /** @var \App\External\PayPal $paypal */
          $paypal->doSomething();
            5 days later

            phptools code like

            $paypal = app(PayPal::class);

            needs the app() function to be annotated so the editor will understand its return type.

            There are several ways of doing so, but I guess the app() function is from Laravel package so you cannot change it.

            • using generics:
              /**
               * @template TName
               * @param class-string<TName> $abstract
               * @return TName
               */
              function app($abstract = null, array $parameters = []) {
            • or using the (usually generated) .phpstorm.meta.php
              \app(0), map([
                      '' => '@',
                      ]);

              JakubMisek

              1. Yes, it is Laravel but I need it only 2 or 3 functions.

              2. Must the filename be .phpstorm.meta.php? Where should it be located?

                phptools

                Must the filename be .phpstorm.meta.php? Where should it be located?

                Yes, it's a special notation introduced by JetBrains (docs).

                The file can be anywhere in your workspace, named .phpstorm.meta.php with the following content:

                (edited)

                namespace PHPSTORM_META {
                  override(
                    \app(0), map([ '' => '@', ])
                  );
                }

                Usually, it's generated using tools like https://github.com/barryvdh/laravel-ide-helper

                  9 days later

                  Let me manually create the file and try. Thanks!

                  I created the .phpstorm.meta.php file in 1 of the folders of my multiroot workspace, with and without <?php.

                  Still doesn't detect.

                    phptools sorry for that! the snippet was not complete.

                    This is correct:

                    namespace PHPSTORM_META {
                      override(
                        \app(0), map([ '' => '@', ])
                      );
                    }
                      Write a Reply...