Мне нужно знать о магической функции __isset()
и нормальной функции isset()
. На самом деле, какова реальная разница между php language construct isset()
и магическим методом php __isset()
? Когда я google, они сказали, что __isset()
– волшебная функция. В чем разница между общими функциями php и магическими функциями в php?
isset()
Это языковая конструкция, которая проверяет инициализацию переменных или свойств класса:
$a = 10; isset($a); // true isset($a, $b); // false class Test { public $prop = 10; } $obj = new Test; isset($obj->prop); // true
__isset()
Это волшебный метод, который вызывается, когда isset()
или empty()
проверяет несуществующее или недоступное свойство класса:
class Test { public function __isset($name) { echo "Non-existent property '$name'"; } } $obj = new Test; isset($obj->prop); // prints "Non-existent property 'prop'" and return false
isset() __isset()
Языковая конструкция | Волшебный метод | Всегда возвращайте bool | Результат зависит от пользовательской логики * | Должен быть вызван в коде | Вызывается автоматически по событию | Неограниченное количество параметров | Имеет только один параметр | Может использоваться в любой области | Должен быть определен как метод ** | Является зарезервированным ключевым словом | Не зарезервированное ключевое слово | Невозможно переопределить (ошибка анализа) | Может быть переопределено в расширенном классе ***
__isset()
любом случае будет автоматически выбран как bool
.
На самом деле вы можете определить пользовательскую функцию __isset()
но она не имеет ничего общего с магическим методом.
См. Этот пример .
В отличие от общих функций, можно определять только в области видимости класса и автоматически активировать определенные события, такие как: недоступный вызов метода, сериализация класса, когда unset()
используется для недоступных свойств и т. Д. См. Также эту официальную документацию: Перегрузка .
__isset – волшебный метод. Магические методы – это методы, называемые внутренне.
Рассмотрим следующий код
<?php // Declare a simple class class TestClass { public $foo; public function __construct($foo) { $this->foo = $foo; } public function __toString() { return $this->foo; } } $class = new TestClass('Hello'); echo $class; ?>
здесь _ toString – волшебный метод, но вы не будете его называть. Когда строка echo $ class; выполняется. PHP знает, что теперь я должен рассматривать объект $ class как строку и обрабатывать любой объект как метод вызова string- toString, если он реализуется в этом классе.
Все магические методы называются косвенным образом.
Другой пример, как следует
<?php class CallableClass { public function __invoke($x) { var_dump($x); } } $obj = new CallableClass; $obj(5); var_dump(is_callable($obj)); ?>
Аналогично, в приведенном выше коде var_dump (is_callable ($ obj)); косвенно вызывает метод __invoke magic.
Прежде всего позвольте мне рассказать вам, что делает функция isset (). Функция isset () проверяет, установлено ли значение или оно равно null. Функция _ isset () является магическим методом в PHP. Любая функция с «_ » в начале – это волшебный метод в PHP. Теперь __isset () вызывается вызовом isset () или empty () в недоступных свойствах, под этим подразумеваются те свойства, которые не были определены в классе и явно определены во время выполнения. Вот фрагмент кода, который должен помочь вам понять это лучше:
<?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; } /** As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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"; ?>
не<?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; } /** As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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"; ?>
с<?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; } /** As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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"; ?>
Простыми словами, __isset () помогает isset () работать над защищенными / частными vars в классе .
Пример:
class test { public $x = array(); }
в вышеуказанном классе вы можете сделать это isset($test->x['key'])
поскольку $x
является общедоступным
но здесь
class test { protected $x = array(); function __isset($key) { return isset($this->x[$key]); } }
$x
защищен, и вы не можете получить к нему доступ, поэтому мы создали __isset()
чтобы помочь нам использовать isset($x['key'])
вы можете сказать, что __isset()
– это просто мост для isset()
Магические функции автоматически вызывается (срабатывает), когда что-то происходит. Ваш php-код должен быть вызван нормальными функциями.
В вашем случае: __isset () будет автоматически вызываться, когда у вас есть isset (), который пытается получить не доступное свойство.
Пример:
root@folgore:/tmp/php# cat a.php <?php class a { private $att1; public $att2; function __isset($field) { echo "__isset invoked for $field\n"; } } $obj=new a(); // __isset will be triggered: isset($obj->att1); // __isset will not be triggered: isset($obj->att2); root@folgore:/tmp/php# php a.php __isset invoked for att1
В чем разница между общими функциями php и магическими функциями в php?
Общая функция PHP объявляется и доступна с ожидаемыми входами и результатами, но их следует вызывать. Напротив, магические функции определены в PHP, но если они определены в классе, то они будут вызваны автоматически. Например, isset()
является функцией PHP
Определите, установлена ли переменная и не является NULL
Но __isset () является перегрузкой свойств класса.
Перегрузка в PHP предоставляет возможность динамически «создавать» свойства и методы. Эти динамические объекты обрабатываются с помощью магических методов, которые можно установить в классе для различных типов действий. Методы перегрузки вызываются при взаимодействии со свойствами или методами, которые не были объявлены или не видны в текущей области.
Он будет называться магически позади сцены, как описано выше, если объявлено в классе. Давайте экспериментируем перегрузку свойств класса PHP.
<?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; } /* As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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; //__set() is called when 'a' property is not visible outside of class $obj->a = 1; //__get() is called when 'a' property is not visible outside of class echo "a: ".$obj->a . "\n\n"; //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); unset($obj->a); //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); echo "\n"; //__isset() is not called as 'declared' property is visible outside of class var_dump(isset($obj->declared)); //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__set() is not called as 'declared' property is visible outside of class $obj->declared = 3; //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__isset() is called as 'hidden' property is not visible outside of class var_dump(isset($obj->hidden)); 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"; var_dump($obj->hidden); ?>
не<?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; } /* As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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; //__set() is called when 'a' property is not visible outside of class $obj->a = 1; //__get() is called when 'a' property is not visible outside of class echo "a: ".$obj->a . "\n\n"; //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); unset($obj->a); //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); echo "\n"; //__isset() is not called as 'declared' property is visible outside of class var_dump(isset($obj->declared)); //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__set() is not called as 'declared' property is visible outside of class $obj->declared = 3; //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__isset() is called as 'hidden' property is not visible outside of class var_dump(isset($obj->hidden)); 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"; var_dump($obj->hidden); ?>
с<?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; } /* As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ 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; //__set() is called when 'a' property is not visible outside of class $obj->a = 1; //__get() is called when 'a' property is not visible outside of class echo "a: ".$obj->a . "\n\n"; //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); unset($obj->a); //__isset() is called when 'a' property is not visible outside of class var_dump(isset($obj->a)); echo "\n"; //__isset() is not called as 'declared' property is visible outside of class var_dump(isset($obj->declared)); //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__set() is not called as 'declared' property is visible outside of class $obj->declared = 3; //__get() is not called as 'declared' property is visible outside of class echo "declared: ". $obj->declared . "\n\n"; //__isset() is called as 'hidden' property is not visible outside of class var_dump(isset($obj->hidden)); 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"; var_dump($obj->hidden); ?>
Выведенный выше код будет выводиться
Setting 'a' to '1' Getting 'a' a: 1 Is 'a' set? bool(true) Unsetting 'a' Is 'a' set? bool(false) bool(true) declared: 1 declared: 3 Is 'hidden' set? bool(false) Let's experiment with the private property named 'hidden': Privates are visible inside the class, so __get() not used... 2 Privates not visible outside of class, so __get() is used... Getting 'hidden' NULL
Он говорит, что свойство «hidden» не установлено и показывает bool(false)
но значение echos out «2» позже, потому что свойство «hidden» не отображается вне класса и вызывает __isset()
но это также не задается в 'data', поэтому возвращает bool(false)
. В функции getHidden()
хотя он возвращает закрытое свойство объекта, которое видимо для внутренних объектов объекта. В последнем var_dump($obj->hidden)
он вызывает метод __get()
и возвращает NULL. Потому что в методе __get()
он ищет data['hidden']
которые являются NULL
.
Примечание: здесь приведен пример PHP Manuel: перегрузка с некоторыми изменениями.
Надеюсь это поможет!
isset()
для переменных и __isset()
для свойств класса.