Ошибка Yii CList - нет метода или замыкания с именем "setReadOnly"

У меня есть базовая функция, которая использует CList - по какой-то причине я получаю следующую ошибку:

CList and its behaviors do not have a method or closure named "setReadOnly".

Мой php код

$list = new CList(array('python', 'ruby'));
$anotherList = new Clist(array('php'));
    var_dump($list);
$list->mergeWith($anotherList);
    var_dump($list);
$list->setReadOnly(true); // CList and its behaviors do not have a method or closure named "setReadOnly". 

Может кто-нибудь объяснить, почему я получаю эту ошибку?

PS Я скопировал этот код прямо из недавней книги по Yii... так что я немного озадачен

// Обновление: добавлено var_dump до и после mergeWith()

object(CList)[20]
  private '_d' => 
    array (size=2)
     0 => string 'python' (length=6)
     1 => string 'ruby' (length=4)
  private '_c' => int 2
  private '_r' => boolean false
  private '_e' (CComponent) => null
  private '_m' (CComponent) => null

object(CList)[20]
  private '_d' => 
    array (size=3)
    0 => string 'python' (length=6)
    1 => string 'ruby' (length=4)
    2 => string 'php' (length=3)
  private '_c' => int 3
  private '_r' => boolean false
  private '_e' (CComponent) => null
  private '_m' (CComponent) => null

1 ответ

Решение

Метод CListsetReadOnly() защищен и поэтому не может быть вызван из используемой области, только из самого себя или наследующих классов. См. http://php.net/manual/en/language.oop5.visibility.php.

Тем не менее, класс CList позволяет списку быть установленным только для чтения в его конструкторе

public function __construct($data=null,$readOnly=false)
{
    if($data!==null)
    $this->copyFrom($data);
    $this->setReadOnly($readOnly);
}

Так...

$list = new CList(array('python', 'ruby'), true); // Passing true into the constructor
$anotherList = new CList(array('php'));
$list->mergeWith($anotherList);

Приводит к ошибке

CException The list is read only. 

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

Вы можете подумать, что при объединении последующих CLists вы можете установить в конце только для чтения значение true, однако mergeWith() объединяет только массив данных _d, а не другие переменные класса, поэтому он остается ложным.

$list = new CList(array('python', 'ruby'));
$anotherList = new CList(array('php'));
$yetAnotherList = new CList(array('javacript'), true);

$list->mergeWith($anotherList);
$list->mergeWith($yetAnotherList);

var_dump($list); // ["_r":"CList":private]=>bool(false)
Другие вопросы по тегам