Видимость и поведение переменных PHP с помощью магического метода
Этот вопрос связан с: Пример волшебных методов PHP
Я задал этот вопрос в комментарии в принятом ответе, но, думаю, это не было замечено, поэтому я должен создать этот вопрос.
<?php
class Magic {
public $a = "A";
protected $b = array(
"a"=>"A",
"b"=>"B",
"c"=>"C"
);
protected $c = array(1,2,3);
public function __get($v) {
echo "$v,";
return $this->b[$v];
}
public function __set($var, $val) {
echo "$var: $val,";
$this->$var = $val;
}
}
$m = new Magic();
echo $m->a.",".$m->b.",".$m->c.",";
$m->c = "CC";
echo $m->a.",".$m->b.",".$m->c;
?>
Вывод:
b,c,A,B,C,c: CC,b,c,A,B,C
$m->c = "CC";
Здесь у нас уже есть защищенная переменная с таким же именем.
Итак, как это должно вести себя в контексте видимости?
Если он перезаписывает значение защищенной переменной c
, то не является ли это отверстием для петли для защищенные/частные переменные? (Я думаю, что это было бы не так)
Если нет, то оператор: $this->$var = $val;
, похоже, создает общедоступную переменную с тем же именем, которое уже определено как защищенное.
Возможно ли это?
Также, после этого утверждения: $m->c = "CC";
, когда мы снова обращаемся к $m->c
, PHP снова вызывает __get
, как будто c
не имеет публичной видимости.
Означает ли это, что у $this->$var = $val;
нет жизненного времени для немедленного следующего утверждения? (Я думаю, что это тоже было бы не так)
Кто-нибудь может объяснить, пожалуйста, это следует ли вести себя в таких случаях и как это дало такой результат?
2 answers
Похоже, что c
изменяется только методами. Пока он защищен, магические методы разоблачают его.
Если вы посмотрите на этот пример:
class Magic
{
protected $b = 'B';
public function __get($v)
{
return 'C';
}
public function __set($v, $val)
{
$this->$v = $val;
}
}
$magic->b = 'D';
echo $magic->b; // Outputs: C
Первый вызов устанавливает свойство b
в D
, однако, поскольку средство получения жестко запрограммировано для возврата C
, модификатор доступа protected
по-прежнему соблюдается.
РЕДАКТИРОВАТЬ.
Еще одно применение магических геттеров/сеттеров - доступ к коллекциям. Этот пример демонстрирует их гибкость:
class Magic
{
private $properties = array();
public function __get($key)
{
if(isset($this->properties[$key])) {
return $this->properties[$key];
}
}
public function __set($key, $value)
{
$this->properties[$key] = $value;
}
public function dump($return = false)
{
if($return) {
return print_r($this->properties, true);
} else {
print_r($this->properties);
}
}
}
$magic = new Magic();
$magic->a = '123';
$magic->b = '456';
$magic->c = '789';
echo '<pre>';
echo sprintf('A: %s%s', $magic->a, PHP_EOL);
echo sprintf('B: %s%s', $magic->b, PHP_EOL);
echo sprintf('C: %s%s', $magic->c, PHP_EOL);
echo PHP_EOL;
echo $magic->dump(true);
Вывод:
A: 123
B: 456
C: 789
Array
(
[a] => 123
[b] => 456
[c] => 789
)
Они являются всего лишь функциями и поэтому следуют одним и тем же правилам, разница лишь в методе, в котором они вызываются.
Ваши геттер и сеттер применяются к разным переменным.
Получатель обращается к элементу свойства $b Установщик обращается непосредственно к указанному свойству.
Видимость здесь не имеет значения, так как весь ваш доступ происходит из методов класса. Таким образом, они могут получить доступ к общедоступным и защищенным объектам без каких-либо различий.
Думайте о волшебной функции как о обычной функции со странным названием. Это то же самое, что получить к ним доступ в этом способ:
$m->__get("a");
$m->__set("c", "CC");