Обработка свойств PHP, подобных свойствам в C# (геттер и сеттер)


Я проводил некоторое исследование в течение долгого времени и хотел знать, можно ли использовать свойства в классе PHP, как в C#, я нашел эти вопросы, которые дают несколько хороших ответов и указателей, но на самом деле не помогли мне:

Хотя, как я уже сказал, они дают хорошие ответы, я все еще не могу определиться с этим, например, я хочу иметь возможность делать что-то вроде:

class Foo 
{
    public $bar
    {
        get { return $this->bar; }
        set { $this->bar = value; }
    }
}

Но я не могу!

Каков наилучший способ сделать это в рамках ограничений PHP?

Вот что я смог придумать:

class user
{
    private static $link;
    private static $init;

    private function __construct ()
    {
        global $link;
        static::$link = $link;
    }

    public static function __INIT__ ()
    {
        return static::$init = (null === static::$init ? new self() : static::$init);
    }

    public static $username;

    public function username( $value = '' )
    {
        if ( $value == '' || empty ( $value ) || !$value )
            return static::$username;
        else
            static::$username = $value;
    }
}
Author: Community, 2015-11-10

2 answers

Для этого и существуют волшебные методы PHP. Они позволяют динамически задавать свойства с помощью метода посредника. Здесь позвольте мне показать вам пример:

abstract class GetterSetterExample
{
    public function __get($name)
    {
        $method = sprintf('get%s', ucfirst($name));

        if (!method_exists($this, $method)) {
            throw new Exception();
        }

        return $this->$method();
    }

    public function __set($name, $v)
    {
        $method = sprintf('set%s', ucfirst($name));

        if (!method_exists($this, $method)) {
            throw new Exception();
        }

        $this->$method($v);
    }
}

class Cat extends GetterSetterExample
{
    protected $furColor;

    protected function getFurColor()
    {
        return $this->furColor;
    }

    protected function setFurColor($v)
    {
        $this->furColor = $v;
    }
}

$cat = new Cat();
$cat->furColor = 'black';

Да... меня это тоже пугает.

Вот почему большинство людей довольствуются использованием методов, подобных описанным в Cat, но общедоступных. По-видимому, обсуждается вопрос о добавлении "настоящих" геттеров и сеттеров, но, похоже, существует много конфликтов между теми, кто ненавидит их из-за проблем с удобочитаемостью, семантикой и принцип...

 3
Author: Flosculus, 2015-11-10 14:53:34

Может быть, вам нужно подумать, действительно ли это необходимо. Это просто стенография для написания геттеров и сеттеров.

private String _name;

public String Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

Выполняет точно такую же функцию, как:

private $_name;

public function getName()
{
    return $_name;
}

public function setName($name)
{
    $_name = $name;
}

Есть только разница в вызове:

C#  : Object.Name = "This is my Name";
PHP : Object->setName ("This is my Name");

Если вы действительно предпочитаете синтаксис C# (что, на мой взгляд, просто привычка), я думаю, что ответ Флоскулуса - единственный вариант. Это не так сложно, если вы понимаете, что делает код. Для информации:

__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.

В этом примере furColor является недоступна, так как это защищенная переменная.

Так что же здесь происходит $cat->furColor = 'black.

  • Furcolor недоступен, поэтому вызывается магический метод __set.
  • Он создает сеттер в GetterSetterExample с именем setFurColor и проверяет, существует ли он.
  • Да, он существует, потому что Cat реализовал его.
  • setFurColor вызывается и устанавливается переменная.

В финале также этот код выполняет то же самое, что и общие геттеры и сеттеры из приведенного выше примера. Это просто "обходной путь" для имитации свойств C#. Итак, возвращаясь к моему первому вопросу этого ответа, необходимо ли это? На мой взгляд, это не так. PHP не поддерживает свойства, поэтому не имеет четкого смысла, почему вы пытаетесь его имитировать. Общие геттеры и сеттеры - это правильный путь, и, как показано в моих примерах, он делает то же самое. Магические методы медленны, и удачи, если вы хотите сделать это безопасным способом. Пример кода Flosculus не является сложным, но это приложение может стать (ненужный) комплекс.

 3
Author: S.Pols, 2015-11-11 08:34:23