Singleton

firep91613

Новичок
Здравствуйте. Я не давно начал изучение PHP, дошел до паттерна Singleton. Не до конца разобрался с кодом, прошу помочь.
PHP:
namespace Singleton;

final class Settings
{
   // Почему здесь ?Settings? Создается же объект класса Settings
    private static ?Settings $_object;
    private ?array $_settings;

    private function __construct()
    {
        // Зачем здесь нужна локальная переменная?
        $_settings = [];
    }

    private function __clone() {}

    public static function get() : Settings
    {
        self::$_object ??= new self();
        return self::$_object;
    }

    public function __get($key) : mixed
    {
        if (array_key_exists($key, $this->_settings)) {
            return $this->_settings[$key];
        } else {
            return null;
        }
    }

    public function __set($key, $value) : void
    {
        // Тут так и должно быть? Свойство же $_settings
        $this->_settings[$key] = $value;
    }
}
 

AnrDaemon

Продвинутый новичок
В конструкторе код неверный.
__get можно было написать проще.
get тоже.
 

AnrDaemon

Продвинутый новичок
Вдогонку: если хочешь получить синглетон, который не будет антипаттерном,

PHP:
namespace firep91613\Singleton;

final class Settings {

    private static array $_store = [];
    private array $_settings = [];

    private function __construct(string $ident) {
        static::$_store[$ident] = $this;
    }

    public static function get(string $ident = "default"): Settings {
        return static::$_store[$ident] ?? new static($ident);
    }

    public function __isset($key): bool {
        return isset($this->_settings[$key]);
    }

    public function __get($key): mixed {
        return $this->_settings[$key] ?? null;
    }

    public function __set($key, $value): void {
        $this->_settings[$key] = $value;
    }
}
 

firep91613

Новичок
AnrDaemon, правильно ли я понимаю, что __isset - магический метод? Это типо когда isset($obj->prop) он будет вызываться?
 

AnrDaemon

Продвинутый новичок
Синглетон как паттерн сам по себе "не очень". Если есть какие-то аргументы кроме этого, с удовольствием послушаю.
 

weregod

unserializer
Синглетон как паттерн сам по себе "не очень". Если есть какие-то аргументы кроме этого, с удовольствием послушаю.
Один раз пригодился, CMS-ке ядро хранить, чтобы сторонние разработчики (было кодовое API) его не разнесли, а так да, скорее антипаттерн )
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Синглетон как паттерн сам по себе "не очень". Если есть какие-то аргументы кроме этого, с удовольствием послушаю.
Как антипаттерн да, но мне не нравится что нет оформления кода, хотя код не твой, а автора

Не закрыт __clone()

Есть static::

Ключи я бы приводил в хранилище к стрингам

Мне этого уже достаточно.

Ну и полный звездос это get() метод, который тебе почему-то и сам объект делает (из названия вообще непонятчто что он творит) и вроде как бы с него должен бы доставать что-то изнутри, а вот хрен...
 

AnrDaemon

Продвинутый новичок
> Не закрыт __clone()

Прошляпил.

> Ну и полный звездос это get() метод, который тебе почему-то и сам объект делает

Поскольку конструктор приватный, я не стал сильно заморачиваться с кодом. Если ключ в массиве есть, отдаётся существующий инстанс, если нет - создаётся новый инстанс, сам себя пишет в массив и отдаётся.

Pun intended.
 
Сверху