В то время как обещания и обратные вызовы хорошо работают во многих ситуациях, боль в задней части выражает нечто вроде:
if (!name) {
name = async1();
}
async2(name);
. В итоге вы пройдете через async1
; проверьте, не определено ли name
или нет, и соответственно вызовите обратный вызов.
async1(name, callback) {
if (name)
callback(name)
else {
doSomething(callback)
}
}
async1(name, async2)
Хотя в в порядке хорошо , это раздражает, когда у вас много подобных случаев и обработка ошибок.
Fibers
помогает в решении проблемы.
var Fiber = require('fibers')
function async1(container) {
var current = Fiber.current
var result
doSomething(function(name) {
result = name
fiber.run()
})
Fiber.yield()
return result
}
Fiber(function() {
var name
if (!name) {
name = async1()
}
async2(name)
// Make any number of async calls from here
}
Вы можете проверить проект здесь .
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()
Language construct | Magic method | Always return bool | Result depends on custom logic* | Must be invoked in code | Called automatically by event | Unlimited number of parameters | Has only one parameter | Can be used in any scope | Must be defined as method** | Is a reserved keyword | Not a reserved keyword | Can't be redefined (Parse error) | Can be redefined in extended class***
__isset()
результат в любом случае будет автоматически лить как bool
.
На самом деле вы можете определить пользовательская функция __isset()
, но она не имеет ничего общего с магическим методом.
См. в этом примере .
В отличие от общих функций, они могут быть определены только в области видимости класса и автоматически активируются при определенных событиях, таких как: недоступный вызов метода, сериализация класса, когда unset()
используется для недоступных свойств и т. д. См. Также эту официальную документацию: Перегрузка .
Магические функции автоматически вызывается (срабатывает), когда что-то происходит. Нормальные функции должны быть специально вызваны вашим 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
__ 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 как строку и рассматривать любой объект как метод вызова _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()
- для свойств класса.
простыми словами, __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 и магическими функциями в 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); ?>
Вышеприведенный код выведет
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» позже, потому что Свойство «скрытое» не отображается вне класса и вызывает магическую функцию__isset()
, но оно также не задано в «данных», поэтому оно возвращаетbool(false)
. В функцииgetHidden()
, хотя он возвращает закрытое свойство объекта, которое видимо для внутренних объектов объекта. В последнемvar_dump($obj->hidden)
он вызывает метод__get()
и возвращает NULL. Потому что в методе__get()
он ищетdata['hidden']
, который являетсяNULL
.Примечание: пример здесь из PHP Manuel: перегрузка с некоторыми изменениями.
Надеюсь, это поможет!
Прежде всего позвольте мне рассказать вам, что делает функция 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";
?>