Функциите __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state и __clone са наречени магически в класовете на php. Не може да имате функция с такива имена в класовете освен ако не искате да ползвате магическата им функционалност.
Конструктори и деконструктори
__construct
PHP 5 позволява на разработчиците да декларират конструктори на класовете. Класове, които имат метод-конструктор, извикват този метод при всяко създаване на нов обект, така че той е много подходящ за извършване на инициализации, от които обектът се нуждае преди да бъде използван.
Забележка: Конструкторите на родителските класове не се извикват автоматично, ако в даден дъщерен клас е дефиниран конструктор. За да се изпълни конструкторът на родителския клас, е необходимо да се извика parent::__construct() в тялото на конструктора на дъщерния клас.
void __construct ([ mixed $args [, $... ]] )
< ?php
class Foo {
function __construct(){
echo "Hello World";
}
}
$foo = new Foo();// Hello World
__destruct
В PHP 5 е въведен деструкторен метод, по подобие на другите обектно-ориентирани езици като C++. Деструкторът ще се извика в момента, в който обектът бъде унищожен.
void __destruct ( void )
< ?php
class Foo {
function __construct(){
echo "Hello ";
}
function __destruct(){
echo "World";
}
}
$foo = new Foo();// Hello World
Предефиниране на методи
__call ( string $name , array $arguments )
__callStatic ( string $name , array $arguments )
__call() се задейства при извикване на недостъпни методи в контекста на обект.
__callStatic() се задейства при извикване на недостъпни методи в контекста на статично извикване.
Параметърът $name указва името на метода, който се извиква. Параметърът $arguments е масив, съдържаш параметрите, които са предадени към метода $name.
< ?php
class MethodTest {
public function __call($name, $arguments) {
// Забележка: стойността на $name е чувствителна към регистъра.
echo "Извикване на метод на обект '$name' "
. implode(', ', $arguments). "\n";
}
/** От PHP 5.3.0 */
public static function __callStatic($name, $arguments) {
// Забележка: стойността на $name е чувствителна към регистъра.
echo "Извикване на статичен метод '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('в контекста на обект');
MethodTest::runTest('в контекста на статично извикване'); // От PHP 5.3.0
?>
Примерът по-горе ще изведе:
Извикване на метод на обект’runTest’ в контекста на обект
Извикване на статичен метод ‘runTest’ в контекста на статично извикване
Предефиниране на свойства
void __set ( string $name , mixed $value )
mixed __get ( string $name )
bool __isset ( string $name )
void __unset ( string $name )
__set() се изпълнява при запис на данни в недостъпни членове.
__get() се използва за четене на данни от недостъпни членове.
__isset() се задейства при извикване на isset() или empty() с недостъпни членове.
__unset() се извиква когато се използва unset() с недостъпни членове.
Параметърът $name указва името на члена, с който се работи. Параметърът $value на метода __set() указва стойността в която трябва да се установи члена $name.
Предефинирането на членове работи само в контекста на обект. Тези вълшебни методи няма да бъдат извикани в контекста на статично извикване, следователно тези методи не могат да бъдат декларирани като статични.
< ?php
class MemberTest {
/** Място за предефинирани данни. */
private $data = array();
/** Предефиниране не се извършва при декларирани членове. */
public $declared = 1;
/** Предефинирането задейства само при осъществяване на достъп извън тялото на класа. */
private $hidden = 2;
public function __set($name, $value) {
echo "Установяне на '$name' в '$value'\n";
$this->data[$name] = $value;
}
public function __get($name) {
echo "Връщане на стойността на '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Недефинирано свойство посредством __get(): ' . $name .
' в ' . $trace[0]['file'] .
' на ред ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** От PHP 5.1.0 */
public function __isset($name) {
echo "Установен ли е '$name'?\n";
return isset($this->data[$name]);
}
/** От PHP 5.1.0 */
public function __unset($name) {
echo "Унищожаване на '$name'\n";
unset($this->data[$name]);
}
/** Това не е вълшебен метод, просто е тук за пример. */
public function getHidden() {
return $this->hidden;
}
}
$obj = new MemberTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Нека да експериментираме с private свойство именувано 'hidden':\n";
echo "Private свойствата са видими в тялото на класа, така че, не се използва __get()...\n";
echo $obj->getHidden() . "\n";
echo "Private свойствата не са видими извън тялото на класа, така че, се използва __get()...\n";
echo $obj->hidden . "\n";
?>
Примерът по-горе ще изведе:
Установяване на ‘a’ в ’1′
Вземане на стойността на ‘a’
1
Установен ли е ‘a’?
bool(true)
Унищожаване на ‘a’
Установен ли е ‘a’?
bool(false)
1
Нека да експериментираме с private свойство именувано ‘hidden’
Private свойствата са видими в тялото на класа, така че, не се използва __get()…
2
Private свойствата не са видими извън тялото на класа, така че, се използва __get()…
Връщане на стойността на ‘hidden’
Notice: Undefined property via __get(): hidden in
__sleep и __wakeup
serialize() проверява дали в класа ви има функция с вълшебното име __sleep. Ако открие такава, то тази функция се изпълнява преди всяка сериализация. Тя би могла да изчисти обекта и се очаква да върне масив с имената на всички променливи от този обект, които ще бъдат сериалзирани. Ако методът не върне нищо, тогава се сериализира стойността NULL и се генерира грешка от тип E_NOTICE.
Предназначението на __sleep е да затвори всички връзки към бази от данни, които обектът може да има, да съхрани незаписаните данни или да изпълни други подобни изчистващи задачи. Също така функцията може да се използва и в случай, че имате много големи обекти, които няма нужда да бъдат съхранени изцяло.
Обратно – unserialize() проверява за наличието на функция с вълшебното име __wakeup. Ако тя съществува, функцията може да възстанови всички ресурси, които даден обект може да има.
Употребата на __wakeup има за цел да възстанови всички връзки към бази от данни, които може да са били прекъснати по време на сериализацията и за извършване на други повторно-инициализиращи задачи.
__toString
Методът __toString позволява на даден клас да реши как ще реагира, в случай че бъде преобразуван до низ.
< ?php
// Дефиниция на клас
class TestClass
{
public $foo;
public function __construct($foo) {
$this->foo = $foo;
}
public function __toString() {
return $this->foo;
}
}
$class = new TestClass('Здравей');
echo $class;
?>
Примерът по-горе ще изведе:
Здравей
__invoke
Методът __invoke се извиква, когато даден скрипт направи опит да извика обект, както се извиква функция.
< ?php
class CallableClass {
function __invoke($x) {
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
Примерът по-горе ще изведе:
int(5)
bool(true)
