Overloading
Оновлено: 11.05.2023
Перевантаження в PHP надає засоби для динамічного створення властивостей і методів. Ці динамічні сутності обробляються за допомогою магічних методів, які можна створити в класі для різних типів дій.
Перевантажувальні методи викликаються при взаємодії з властивостями або методами, які не були оголошені або не є видимими у поточній області видимості. Далі у цьому розділі будуть використовуватися терміни недоступні властивості та недоступні методи для позначення такої комбінації оголошення та видимості.
Всі методи перевантаження повинні бути визначені як загальнодоступні.
Зауважте:
Жоден з аргументів цих магічних методів не може бути переданий за посиланням.
Зауважте:
Інтерпретація перевантаження в PHP відрізняється від більшості об'єктно-орієнтованих мов. Перевантаження традиційно надає можливість мати декілька методів з однаковими іменами, але різною кількістю і типами аргументів.
__set() виконується при записі даних у недоступні (protected або private) або неіснуючі властивості.
__get() використовується для читання даних з недоступних (protected або private) або неіснуючих властивостей.
__isset() спрацьовує при виклику isset() або empty() для недоступних (захищених або приватних) або неіснуючих властивостей.
__unset() викликається, коли unset() застосовується до недоступних (protected або private) або неіснуючих властивостей.
Аргумент $name - це ім'я властивості, з якою відбувається взаємодія. Аргумент $value методу __set() вказує значення, до якого слід встановити властивість $name'ed.
Перевантаження властивостей працює тільки в контексті об'єкта. Ці магічні методи не спрацьовують у статичному контексті. Тому ці методи не слід оголошувати статичними. Попередження видається, якщо один з магічних методів перевантаження оголошено статичним.
Зауважте:
Значення, що повертається функцією __set(), ігнорується через те, як PHP обробляє оператор присвоювання. Аналогічно, __get() ніколи не викликається при такому ланцюжку присвоєнь:
Зауважте:
PHP не буде викликати перевантажений метод зсередини того ж самого перевантаженого методу. Це означає, що, наприклад, написання return $this->foo всередині __get() поверне null і видасть E_WARNING, якщо властивість foo не визначено, а не викличе __get() вдруге. Однак, методи перевантаження можуть викликати інші методи перевантаження неявно (наприклад, __set() викликає __get()).
Приклад #1 Перевантаження властивостей методами __get(), __set(), __isset() та __unset()
<?php
class PropertyTest
{
/** Location for overloaded data. */
private $data = array();
/** Overloading not used on declared properties. */
public $declared = 1;
/** Overloading only used on this when accessed outside the class. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name)
{
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Not a magic method, just here for example. */
public function getHidden()
{
return $this->hidden;
}
}
echo "<pre>\n";
$obj = new PropertyTest;
$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 "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>
__call() спрацьовує при виклику недоступних методів у контексті об'єкта.
__callStatic() спрацьовує при виклику недоступних методів у статичному контексті.
Аргумент $name - це ім'я методу, що викликається. Аргумент $arguments - це перечислюваний масив, що містить параметри, які передаються до методу $name'ed.
Приклад #2 Перевантаження методів з допомогою методів __call() та __callStatic()
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context');
?>