Магические методы в ООП

Классы, помеченные как final

Метод final

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

<?php
class BaseClass {
public function test() {
echo "Вызван метод BaseClass::test()\n";
}

final public function moreTesting() {
echo "Вызван метод BaseClass::moreTesting()\n";
}
}

class ChildClass extends BaseClass {
public function moreTesting() {
echo "Вызван метод ChildClass::moreTesting()\n";
}
}
// Выполнение заканчивается фатальной ошибкой:
//Cannot override final method BaseClass::moreTesting()
// (Метод BaseClass::moretesting() не может быть переопределён)
?>

После объявления класса final он не может быть унаследован. Следующий пример вызовет ошибку:

<?php
final class FinalClass {
}

class BogusClass extends FinalClass {
}
?>

Чтобы сделать использование объектов проще, PHP имеет несколько магических методов. Это специальные методы, которые вызываются, когда над объектом производятся определённые действия. Таким образом разработчик может выполнить несколько общих задач относительно просто.

Это методы, которые имеют особое значение, потому как их вызываете не вы, а PHP в определенные моменты. Чтобы не контролировать наступление этих моментов и не вызывать функции вручную вы можете добавлять к своим классам «магические» методы и быть уверенным в том что они будут вызваны автоматически. Все «магические» методы начинаются с двойного символа подчеркивания __ и являются методами объекта (не static), кроме двух: __callStatic и __set_state.
Перечислим их все:

void __construct(mixed $arg1[, mixed $arg2[,...]])
Когда: Вызывается при создании экземпляра объекта. Имеет входное количество параметров таким каким его задаст пользователь, т.е. вы.

void __destruct()
Когда: в момент когда объект подвергается сборке мусора. Т.е. завершает своё существование.

mixed __get(string $name)
Когда: при попытке запросить свойство объекта, которого он не имеет (или недоступному из за private / protected модификатора). Именно имя этого несуществующего свойства он и передаст в качестве первого параметра. А что с этим делать – ваша забота.

void __set (string $name, mixed $value)
Когда: запустится, если вы попытаетесь несуществующему (или недоступному из-за private / protected модификатора) свойству присвоить какое-либо значение. В функцию будут переданы имя этого свойства и значение, которое ему пытались установить.

mixed __call (string $name, array $args)
Когда: вызовется, если у объекта была попытка выполнить несуществующий метод. Первым параметром будет имя этого метода, а вторым будет массив входных параметров, которые пытались этой функции передать.

mixed __callStatic (string $name, array $args)
Когда: аналогично __call, но работает с несуществующими статическими методами, т.е. методами которые были вызваны через синтаксис ИмяКласса::ИмяМетода, но не были найдены в классе.

string __toString ()
Когда: вызывается, когда объект пытаются использовать как строку, например, в случае если вы хотите вывести объект через echo. Объект будет представлен как строка, так как вы захотите – он будет представлен тем, что будет возвращено этим методом, т.е. return обязателен.

void __clone ()
Когда: после клонирования объекта оператором clone. Внутри этого метода вы можете использовать $this, чтобы изменить клон который создается.
Зачем: Если в классе используются объекты, то обычное клонирование скопирует лишь ссылки на них, и новых экземпляр будет привязан к данным которые находятся не только внутри него, но и в том объекте из которого он клонировался. Выход - клонировать необходимое вручную внутри __clone

bool __isset (string $name)
Когда: сработает при проверке с помощью isset() несуществующих свойств у данного объекта.

void __unset (string $name)
Когда: вызовется, когда применяют функцию unset() на несуществующем свойстве класса. Принимает в качестве первого параметра имя этого свойства.

object __set_state (array $properties)
Когда: внутри вызова var_export(), первым параметром принимает свойства объекта которые собирается сохранить система. Если сделать eval полученного кода, вызовется эта функция

mixed __invoke (mixed $arg1[, mixed $arg2[,...]])
Когда: вызывается, когда объект используется в стиле функции. В метод __invoke передаются все параметры, которые вы передали, используя объект в качестве функции. Но они передадутся не в одном первом аргументе, а в обычном виде. Чтобы получить параметры в массиве можно, конечно же, воспользоваться функцией func_get_args ()

array __sleep ()
Когда: вызывается внутри функции serialize и определяет какие члены объекта надо сохранить, для этого вы должны вернуть массив содержащий строки-имена членов которые должны быть записаны.

void __wakeup ()
Когда: вызывается когда метод "просыпается" десериализацией внутри unserialize

Константа __CLASS__ возвращает имя класса, в котором она вызывается;

Чтобы избежать ошибки, если скрипт попытается вывести MyClass как строку, используется другой магический метод __toString().

Без использования __toString() попытка вывести объект как строку приведёт к фатальной ошибке. Попробуйте использовать функцию echo, чтобы вывести объект без применения магического метода:

class MyClass

{

public $prop1 = "Свойство класса ";

public function __construct()

{

echo 'Создан объект класса "', __CLASS__, '"!<br />';

}

public function __toString()

{

echo "Используем метод toString: ";

return $this->prop1;

}

}

// Создаем новый объект

$obj = new MyClass;

// Выводим объект как строку

echo $obj;

Обращения к свойствам объекта могут быть перегружены с использованием методов __call, __get и __set. Эти методы будут срабатывать только в том случае, если объект или наследуемый объект не содержат свойства, к которому осуществляется доступ. Синтаксис такой:

void __set (string имя, mixed значение)

void __get (mixed имя)

С помощью этих методов обращения к свойствам класса могут быть перегружены с целью выполнения произвольного кода, описанного в классе. В аргументе имя передаётся имя свойства, к которому производится обращение. Аргумент значение метода __set() должен содержать значение, которое будет присвоено свойству класса с именем имя.

Пример перегрузки с использованием __get и __set:

<?php
class Setter {
public $n;
private $x = array("a" => 1, "b" => 2, "c" => 3);

function __get($nm) {
print "Читаем [$nm]\n";

if (isset($this->x[$nm])) {
$r = $this->x[$nm];
print "Получили: $r\n";
return $r;
} else {
print "Ничего!\n";
}
}

function __set($nm, $val) {
print "Пишем $val в [$nm]\n";

if (isset($this->x[$nm])) {
$this->x[$nm] = $val;
print "OK!\n";
} else {
print "Всё плохо!\n";
}
}
}

$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a++;
$foo->z++;
var_dump($foo);
?>

Результатом выполнения рассмотренного скрипта будет:

Пишем 100 в [a]
OK!
Читаем [a]
Получили: 100
Пишем 101 в [a]
OK!
Читаем [z]
Ничего!
Пишем 1 в [z]
Всё плохо!
object(Setter)#1 (2) {
["n"]=>
int(1)
["x:private"]=>
array(3) {
["a"]=>
int(101)
["b"]=>
int(2)
["c"]=>
int(3)
}
}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: