Asked  7 Months ago    Answers:  5   Viewed   72 times

In my PHP application I have a base class for all database objects, which is further extended by specific model classes. It goes on like this (simplified):

abstract class Model extends Collection {

    (...)

    function __construct(string $primary_key, string $value) {
        $data = MysqlDB::instance() -> select(static::TABLE, implode(',', static::COLUMNS), "$primary_key="$value"");
        if (count($data) != 1)
            throw new ModelException('Select condition uncertain');
        parent::__construct($data[0]);
    }

    public static function getById(string $id) : ?Model {
        try {
            return new static('id', $id);
        } catch (ModelException $e) {
            return NULL;
        }
    }

    (...)

}

The point is, I use the getById function on child classes to obtain the needed objects. However, since the return type of getById method is Model, PhpStorm can't figure out what methods the objects has and highlights the ones I use as an error. Consequently, no type-hinting available.

For instance, assuming that final class User extends Model and that class User has method sendNotification, this kind of code:

User::getById($id) -> sendNotification($param1, $param2, ...)

has sendNotification yellowed out as though it did not exist.

I know this isn't that much of an issue, but it's really irritating in terms of that I get distracted by constant redundant warnings and that I can't use type-hinting in such a usage case.

 Answers

12

Try with actual PHPDoc for your getById() where you specify dynamic type (e.g. @return static or @return $this).

That's the most common way of providing such "this class and its' children" typehint.


Another possible option is kind of the same .. but using PHP 7.1 functionality (so no PHPDoc blocks).

Try using self as return type instead of Model. I mean here:

public static function getById(string $id) : ?Model {

use this instead:

public static function getById(string $id) : ?self {

But for this one you should use PhpStorm 2017.2 EAP build as 2017.1.x has issues with that (see https://stackoverflow.com/a/44806801/783119 as an example).

Saturday, May 29, 2021
 
tiny
answered 7 Months ago
84

One code sample I have got from a website, but it was difficult for me to understand the output. I am sharing the code

This code is an exact replica from the PHP Manual of the Late Static Binding concept..

Explanation of this code from the manual..

Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like parent:: or self:: will forward the calling information.

Source

So let me explain in depth...

When you do .. C::test(); , The test() under the class B will be called as there is no test() available on class C.

So you are obviously here..

   public static function test() 
   {
      A::foo();
      parent::foo();
      self::foo();
   }

Case 1 : A::foo();

As you read this from the above statement.. Late static bindings' resolution will stop at a fully resolved static call with no fallback , so since it is a fully resolved static call , you will get an output of A

Case 2 & 3 : parent::foo(); and self::foo();

Again, from the above statement.. static calls using keywords like parent:: or self:: will forward the calling information.

So this will obviously print C and C .. because since you did C::test(); , The class C is the actual caller.

Wednesday, March 31, 2021
 
Daveel
answered 9 Months ago
56

You can specify the property type in your subclass without introducing new code, using the @property annotation:

/**
 * @property myModel $_model
 */
class myNewController extends myController
Wednesday, March 31, 2021
 
borrible
answered 9 Months ago
31

The use of late static binding only changes the method that gets chosen for the call. Once the method is chosen, visibility rules are applied to determine whether or not it may be called.

For B, A::test finds and calls A::foo. The comment in B isn't correct--foo isn't copied to B. Since it's private, it is only callable from other methods in A such as A::test.

C fails because the late static binding mechanism locates the new private method C::foo, but A's methods don't have access to it.

I recommended that you reserve late static binding for static fields and methods to avoid confusion.

Saturday, May 29, 2021
 
JakeGR
answered 7 Months ago
75

Step 1

Install PHPStorm 2017.X

Install Xdebug helper for chrome

Step 2

Via ssh (choose a tool like putty, WinSCP, MobaXterm etc.) Install xdebug, in your case laravel gets Ubuntu 16.04 by default with Nginx so we need to follow these instructions The values I used are

; Enable xdebug extension module
zend_extension=/usr/lib64/php/modules/xdebug.so
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_port=9000
xdebug.remote_autostart=1
xdebug.remote_connect_back=1
xdebug.remote_host=10.0.2.2

in /etc/php.d/xdebug.ini

But note that I use my own vagrant installation (homestead is based on Vagrant) with CentOS and apache instead. Restart your virtual machine after config changes.

vagrant / homestead halt

and start again

vagrant / homestead up

Step 3

Config Xdebug helper extension in chrome by right clicking the symbol > options and set your IDE key to PHPStorm in the dropdown menu.

Configure PHPStorm, like a lot

hint: Settings has the shortcut ctrl + alt + s

Check the following settings. Don't forget to add both http and https in the Servers Setting and most important, don't read over the path mappings part. enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

And last but not least click these buttons, the first button with the phone horn actually has reversed icons in my opinion: when debugging it should have the little green part, altough logically red would mean stop, now it means start.

enter image description here

button 2 starts your url with a session var in the query string!

P.s. from your question: I think you need to go 1 level up root of laravel instead of public folders

edit: I just installed homestead at home and it comes with xdebug installed: enter image description here

Thursday, July 29, 2021
 
Axalix
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share