Класове и обекти (PHP 5)
PHP Manual

Предефиниране

Предефинирането в PHP осигурява средства за динамично "създаване" на членове и методи. Динамичните елементи се обработват посредством вълшебни методи, които могат да бъдат добавени към даден клас, с цел извършване на различни операции.

Предефиниращите методи се извикват при осъществяване на достъп до членове и методи, които не са декларирани или не са видими в текущата област на действие. По-нататък в раздела ще се използват термините "недостъпни членове" и "недостъпни методи" за указване на това съчетание от декларация и видимост.

Всички предефиниращи методи трябва да се декларират като public.

Забележка: Параметрите на тези вълшебни методи не могат да бъдат предавани по референция.

Забележка: Интерпретирането на "предефинирането" в PHP е различно от това на повечето обектно-ориентирани езици. Предефинирането обикновено предоставя възможността да съществуват множество методи с едно и също име, но с различен брой и тип на параметрите

Дневник на промените

Версия Описание
5.1.0 Добавени са __isset() и __unset().
5.3.0 Добавен е __callStatic(). Добавено е предупреждение за прилагане на public видимост и нестатично деклариране.

Предефиниране на свойства

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.

Предефинирането на членове работи само в контекста на обект. Тези вълшебни методи няма да бъдат извикани в контекста на статично извикване, следователно тези методи не могат да бъдат декларирани като статични.

Example #1 Пример за предефиниране с __get, __set, __isset и __unset

<?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;
    }
}


echo 
"<pre>\n";

$obj = new MemberTest;

$obj->1;
echo 
$obj->"\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 <file> on line 70 in <file> on line 29

Предефиниране на методи

mixed __call ( string $name , array $arguments )
mixed __callStatic ( string $name , array $arguments )

__call() се задейства при извикване на недостъпни методи в контекста на обект.

__callStatic() се задейства при извикване на недостъпни методи в контекста на статично извикване.

Параметърът $name указва името на метода, който се извиква. Параметърът $arguments е масив, съдържаш параметрите, които са предадени към метода $name.

Example #2 Предефиниране на методи с __call и __callStatic

<?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' в контекста на статично извикване

Класове и обекти (PHP 5)
PHP Manual