Обработка свойств PHP, подобных свойствам в C # (getter & amp; setter)

В течение долгого времени я проводил некоторые исследования и хотел знать, можно ли использовать свойства в классе 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;
}
}

4

Решение

Вот для чего нужны магические методы 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

Другие решения

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

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 # (который, на мой взгляд, просто привычка), я думаю, что ответ Flosculus — единственный вариант. Это не так сложно, если вы понимаете, что делает код.
Для информации:

__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

По вопросам рекламы [email protected]