Получить и установить (приватное) свойство в PHP как в C # без использования перегрузки магического метода getter setter - PullRequest
5 голосов
/ 07 февраля 2011

Сводка

Пример кода:

Class People {
    // private property.
    private $name;

    // other methods not shown for simplicity.
}

Прямо вперед.Позвольте мне предположить, что $name является PRIVATE членом класса (или свойством, переменной, полем, вызывайте его как хотите) .Есть ли способ сделать это в PHP:

$someone = new People();
$someone->name = $value;
$somevar = $someone->name;

БЕЗ с использованием __get($name) и __set($name, $value).


Фон

Мне нужно было проверить назначенное $value, поэтому мне просто нужен установщик-получатель, подобный этому:

getName();
setName($value);

И НЕ обязательно перегрузка магического метода установщика-получателя, например:

__get($value); 
__set($value, $name);

Тем не менее, мне просто нужен установщик геттера.Но это НЕ , что я хочу.Это просто не похоже на объектно-ориентированное, потому что люди из статического типизированного языка, такого как C ++ или C #, могут чувствовать то же самое, что и я.

Есть ли способ получить и установить частное свойство в PHP, как в C #, без использования перегрузки магического метода установщика-получателя?


Обновление

Почему не магический метод?

  1. Ходят слухи, что магический метод в 10 раз медленнее, чем явный метод установки геттера,Я еще не проверял это, но это хорошая вещь, чтобы иметь в виду. (Выяснилось, что это не так медленно, просто в 2 раза медленнее, см. Результат теста ниже)

  2. Мне нужно собрать все одним огромным методом, если я использую магиюметод, а затем разделить их на разные функции для каждого свойства, как в явном установщике геттера. (На это требование мог бы ответить ircmaxell )

Сравнительный анализ производительности

Мне любопытно, что производительность снизитсямежду магическим методом и явным установщиком получения, поэтому я создал свой собственный тест для обоих методов, и, надеюсь, он может быть полезен всем, кто прочитает это.

С магическим методом и method_exist:

(нажмите здесь , чтобы увидеть код)

  • Геттер стоит 0,0004730224609375 секунды.
  • Сеттер стоит 0,00014305114746094 секунды.

С явным установщиком получения:

(нажмите здесь , чтобы увидеть код)

  • Getter стоит 0,00020718574523926 секунды.
  • Setter стоит 7,9870223999023E-5 секунд (это 0,00007xxx).

При этом и метод установки, и метод получения с магическим методом и методомсуществует только в 2 раза дороже, чем явный метод получения.Я думаю, что все еще приемлемо использовать это для системы малого и среднего масштаба.

Ответы [ 4 ]

7 голосов
/ 07 февраля 2011

Неа.

Однако, что не так с использованием __get и __set, которые действуют как динамические прокси для getName() и setName($val) соответственно?Что-то вроде:

public function __get($name) { 
    if (method_exists($this, 'get'.$name)) { 
        $method = 'get' . $name; 
        return $this->$method(); 
    } else { 
        throw new OutOfBoundsException('Member is not gettable');
    }
}

Таким образом, вы не помещаете все в один метод монстра, но вы все равно можете использовать синтаксис $foo->bar = 'baz'; с закрытыми / защищенными переменными-членами ...

3 голосов
/ 19 августа 2013
ReflectionClass is your salvation

Я знаю, что для Хендры уже слишком поздно, но я уверен, что это будет полезно для многих других.

В ядре PHP есть класс с именем ReflectionClass, который может манипулировать всем в области объекта, включаявидимость свойств и методов.

На мой взгляд, это один из лучших классов в PHP.

Позвольте мне показать пример:

Если у вас есть объект счастная собственность, и вы хотите изменить ее извне

$reflection = new ReflectionClass($objectOfYourClass);
$prop = $reflection->getProperty("PrivatePropertyName");
$prop->setAccessible(true);
$prop->setValue($objectOfYourClass, "SOME VALUE");
$varFoo = $prop->getValue();

То же самое вы можете сделать с методами eighter;

Я надеюсь, что смогу помочь;

2 голосов
/ 07 февраля 2011

Если использование магических свойств кажется неправильным, как уже отмечалось другими авторами, вы также можете рассмотреть ReflectionClass :: getProperty и ReflectionProperty :: setAccessible .

Или реализуйте необходимые методы getter и setter в самом классе.

В ответ на поднятую вами проблему языковых возможностей я бы сказал, что наличие языка с динамической типизацией отличается от языка с типизированной статической типизацией.ожидается.Каждый язык программирования с ООП реализует его несколько по-своему: Объектно-ориентированные языки: сравнение .

0 голосов
/ 04 февраля 2014
class conf_server
{

private $m_servidor="localhost";
private $m_usuario = "luis";
private $m_contrasena = "luis";
private $m_basededatos = "database";

public function getServer(){
    return $this->m_servidor;
}
public function setServer($server){
    $this->m_servidor=$server;
}
public function getUsuario(){
    return $this->m_usuario;
}
public function setUsuario($user){
    $this->m_usuario=$user;
}
public function getContrasena(){
    return $this->m_contrasena;
}
public function setContrasena($password){
    $this->m_contrasena=$password;
}
public function getBaseDatos(){
    return $this->m_basededatos;
}
public function setBaseDatos($database){
    $this->m_basededatos->$database;
}
}
...