PHP7.3:子クラスで再宣言せずに、可能な限り最悪のスコープで保護された静的プロパティを継承するにはどうすればよいですか?

JValker

私が取り組んでいるアプリケーションでは、MVCスタックのモデル部分はシングルトンを介して動作するように設計されています。各モデルには__getInstanceMethodがあります。

protected static $singleton;
public static function __getInstance(): self {
    if(self::$singleton === null) {
        self::$singleton = __CLASS__;
        self::$singleton = new self::$singleton;
    }
    return self::$singleton;
}

最終結果は、__ getInstance()が同じModelクラスで2回呼び出された場合、両方の時間でまったく同じオブジェクトを返します。

__getInstance()メソッドをモデルの親クラスであるBaseModelに移動し、そのように編集して、コードの重複を減らしようとしました。

class BaseModel {
    protected static $singleton;
    public static function __getInstance(): self {
        if (static::$singleton === null) {
            static::$singleton = static::class;
            static::$singleton = new static::$singleton();
        }
        return static::$singleton;
    }
}
class AModel extends BaseModel {
    protected static $singleton;
    /** ... */
}
class BModel extends BaseModel {
    protected static $singleton;
    /** ... */
}

AModel::__getInstance(); // AModel
BModel::__getInstance(); // BModel

問題は、すべてのModelクラスに$ singletonプロパティを手動で追加する必要があることです。そうしないと、メソッドを呼び出した最初のModelクラスのインスタンスが常に返されます。

class BaseModel {
    protected static $singleton;
    public static function __getInstance(): self {
        if (static::$singleton === null) {
            static::$singleton = static::$class;
            static::$singleton = new static::$singleton();
        }
        return static::$singleton;
    }
}
class AModel extends BaseModel {}
class BModel extends BaseModel {}

AModel::__getInstance(); // AModel
BModel::__getInstance(); // Still AModel

それを避ける方法はありますか?

ヨッシー

「インスタンスマップ」切り替えることができます。例:

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', 'On');

class BaseModel
{
    protected static $instances = [];

    public static function __getInstance(): self
    {
        if (!isset(static::$instances[static::class])) {
            static::$instances[static::class] = new static();
        }

        return static::$instances[static::class];
    }
}

class AModel extends BaseModel
{
}

class BModel extends BaseModel
{
}

echo get_class(AModel::__getInstance()), "\n";
echo get_class(BModel::__getInstance());

https://3v4l.org/qG0qJ


7.4以降では、次のように簡略化できます。

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', 'On');

class BaseModel
{
    private static array $instances = [];

    public static function __getInstance(): self
    {
        return static::$instances[static::class] ??= new static();
    }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ