简体   繁体   中英

PHP class extends Singleton and access to its properties

My singleton class with my child class:

class Api
{
    protected static $instance = null;

    protected $baseUrl = 'http://google.com';
    protected $clientId;
    protected $clientSecret;

    public static function getInstance(string $clientId, string $clientSecret)
    {
        if (self::$instance === null) {
            self::$instance = new self($clientId, $clientSecret);
        }

        return self::$instance;
    }

    protected function __construct(string $clientId, string $clientSecret)
    {
        $this->clientId     = $clientId;
        $this->clientSecret = $clientSecret;
    }

    public function setBaseUrl(string $baseUrl)
    {
        $this->baseUrl = $baseUrl;
    }

    public function user()
    {
        return new User();
    }
}

class User extends Api
{
    public function me()
    {
        var_dump($this->baseUrl); // HERE
    }
}

I would like to use it as follows:

$api = Api::getInstance('abc', 'def');

$api->setBaseUrl('http://google.dev');

$api->user()->me();

How can this script call me() with the value of http://google.dev , inside User ?

Also, how can I set User to deal with API constructor parameters?

Maybe I'll try to use an existing pattern that is not well implemented in my example?

So the problem is that when you call user() it creates a brand new instance of your User class... So it has no knowledge of the attributes of the Api instance you created, and on which you call setBaseUrl() .

It really depends what your requirements are, here.

If you want Api->user() to return a new user every time, then you could initialize it with the current value of the Api url attribute... But if you then call setBaseUrl on the Api instance again, any user you created before that will still have the old value.

If you want the url to be shared by all instances of the class, then you could make the attribute a static one... But bear in mind that if you do that, you could call $user->setBaseUrl(...) and change the url for all users and the Api instance...

UPDATE

First, I don't think I'd make your User class a subclass of API...

Sounds to me like your API is one thing - providing services to a remote API - and your User is an actual object, separate from the API.

And since your API is a singleton, your User instances can absolutely call it to handle stuff for it:

API::getInstance()->getBaseUrl();

Or call some API method directly:

API::getInstance()->loadAPIObject();

which could return a raw API object, that your User than parses or uses to fill it's own attributes...

Does that help clarify things a bit?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM