PHP - Защищенное свойство недоступно из того же класса библиотеки Zend 1, поэтому используется магия __set() и возникают ошибки

Приложение, которое я создаю, запускается локально, но на промежуточном сервере появляются флаги:

Zend_Form_Exception: Invalid attribute "_name"; must not contain a leading underscore

Проблема связана со строкой 500 файла /library/Zend/Form/Element.php (версия Zend 1), в которой установлено:

$this->_name = $name;

При подготовке (но не локально) в конечном итоге используется магический метод __set(), который терпит неудачу, потому что Zend не позволяет устанавливать свойство, которое выглядит как приватное (из-за подчеркивания), с помощью функции, используемой в __set( ):

$this->setAttrib($key, $value);

Я пытаюсь понять, почему волшебный метод в конечном итоге используется, поскольку if -- перед строкой 500 -- я добавляю:

if (!property_exists($this, '_name')) die();

Я могу сказать, что он знает, что свойство существует. Свойство определено в том же классе, поэтому по существу:

class Zend_Form_Element implements Zend_Validate_Interface {

    protected $_name;

    public function __construct($spec, $options = null) {
         $this->setName($spec);
    }

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

    public function __set($key, $value) {
        $this->setAttrib($key, $value);
    }
}

По какой причине может использоваться магический метод, а не просто установка _name обычным способом?


person Joseph Cape    schedule 19.11.2013    source источник
comment
В Zend Framework 1 было много неудачных дизайнерских решений. Одной из них была чрезмерная зависимость от магических геттеров/сеттеров. Не потратив времени на надлежащий анализ, моя первая догадка заключается в том, что вы просто столкнулись с проблемой, вызванной этими плохими дизайнерскими решениями, или явной ошибкой. Если на одном сервере работает, а на другом нет, то проверьте версии PHP и ZF на обоих и как они настроены.   -  person GordonM    schedule 19.11.2013
comment
У меня тоже есть эта проблема. Два вопроса: 1) у вас версия PHP PHP 5.4.x? 2) эта проблема возникает только для текстовых полей?   -  person bakytn    schedule 18.12.2013


Ответы (2)


Я не уверен, в чем причина использования здесь магии. Zend 1 принял несколько интересных дизайнерских решений в отношении магических методов (как уже упоминалось в других ответах).

Что касается вашего оператора die(), он, вероятно, не вызывается, потому что __isset() реализован в классе, и поэтому property_exists() вернет true.

Если вы пытаетесь понять, что происходит, я бы порекомендовал настроить xdebug.

person Steve B    schedule 19.11.2013
comment
Что касается второго пункта, похоже, не существует магического метода __isset(), связанного с классом, и можно было бы подумать, что все, что заставит property_exists() возвращать значение true, должно препятствовать вызову магического метода __set() (пока свойство также доступен). Кажется, проблема в том, что мой код вызывает внучатый класс, и когда я явно добавляю конструктор в этот внучатый класс с помощью parent::parent::construct(), проблема исчезает. Я бы предпочел не редактировать код фреймворка. У меня настроен Xdebug локально, но на сцене возникают проблемы с настройкой/безопасностью - person Joseph Cape; 21.11.2013

Просто оставить его где-нибудь, так как это определенно интересный (опять же) вопрос. Мы подозреваем, что это связано с тем, что APC хранит класс в памяти, которая становится «поврежденной» (ибо нет другого способа объяснить это). Простое редактирование класса Zend_Form_Element_Text путем вставки одной пустой строки решило проблему для нас. Весело!

person eithed    schedule 12.05.2015