Объявление защищенных переменных в методах - PullRequest
4 голосов
/ 31 июля 2010

Я хорошо огляделся и, похоже, не могу найти ответ на эту проблему.

В основном я использую метод _call для динмической генерации методов get и set, однако при объявленииПеременная PHP по умолчанию общедоступна.Есть ли способ объявить переменную внутри класса защищенной?

function __call($method, $arguments) {
    $prefix = strtolower(substr($method, 0, 3));
    $property = strtolower(substr($method, 3));

    if (empty($prefix) || empty($property)) {
        return;
    }

    if ($prefix == "get" && isset($this->$property)) {
        return $this->$property;
    }

    if ($prefix == "set") {

        $this->$property = $arguments[0];
    }
}

Ответы [ 3 ]

6 голосов
/ 31 июля 2010

Одним из вариантов может быть наличие защищенного массива и установка элемента в этом массиве из вашего волшебного сеттера.

class MyClass {
    protected $_myProperties = array();

    public function __get($name) {
        if (isset($this->_myProperties[$name])) {
            return $this->_myProperties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value) {
        $this->_myProperties[$name] = $value;
    }

    public function __isset($name) {
        return isset($this->_myProperties[$name]);
    }
}
5 голосов
/ 31 июля 2010

Прежде всего, я НАСТОЯТЕЛЬНО рекомендую не returning, если префикс или переменные свойства не установлены. Это сделает отладку ОЧЕНЬ сложной. Вместо этого замените return; на throw new BadMethodCallException('Method Does Not Exist: '.$method);

Во-вторых, разве это не победить точку защищенных переменных? Это позволяет читать и писать для всех свойств без какой-либо проверки. Если вы собираетесь это сделать, вы можете также сделать их публичными.

Лично я считаю $foo->bar = 'baz'; более читабельным, чем $foo->setBar('baz');. Не потому, что это «легче» понять, а потому, что второе излишне многословно.

Лично я бы предложил сделать __get и __set и добавить проверку. Весь смысл защиты переменных заключается в доверии (чтобы вы могли доверять настройкам). Конечно, вы можете использовать рефлексию или подклассификацию, чтобы изменить их, но я обычно предполагаю, что если кто-то заходит так далеко, он заслуживает каких-либо непреднамеренных захватов, если они испортят переменную.

И помните, что если вы используете какой-либо магический метод, вам нужно будет добавить элементы документации, если вы хотите, чтобы ваша IDE подсказывала вам методы / переменные ...

EDIT:

И не забывайте, если вы объявляете методы __get / __set, вы можете переопределить их в дочерних классах. Поэтому, если дочерний элемент объявляет новые переменные, вы можете обработать их там, а затем вызвать parent::__get для обработки переменных по умолчанию. Поэтому не используйте массив только для того, чтобы у вас был один метод для всех детей. Проведите валидацию для членов, о которых вы знаете, и пусть ваши дети справятся со своей валидацией ...

2 голосов
/ 31 июля 2010

Есть ли способ объявить переменную внутри класса как защищенную?

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

Возможно, вы захотите сохранить автоматически сгенерированные свойства в массиве с надлежащей видимостью.

(Есть также __get и __set, но они могут не соответствовать вашим потребностям. Их будут вызывать, только если свойство отсутствует или недоступно. Классы, которые могут касаться защищенных свойств бы обойти их.)

...