Когда использовать __isset и когда использовать _get? [Дубликат]

В то время как обещания и обратные вызовы хорошо работают во многих ситуациях, боль в задней части выражает нечто вроде:

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
}

Вы можете проверить проект здесь .

53
задан Joe 19 February 2014 в 13:46
поделиться

7 ответов

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() используется для недоступных свойств и т. д. См. Также эту официальную документацию: Перегрузка .

41
ответ дан 17 revs, 2 users 92% 28 August 2018 в 11:48
поделиться

Магические функции автоматически вызывается (срабатывает), когда что-то происходит. Нормальные функции должны быть специально вызваны вашим 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
1
ответ дан Alex Jurado - Bitendian 28 August 2018 в 11:48
поделиться

__ 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.

5
ответ дан Hassan 28 August 2018 в 11:48
поделиться

isset() для переменных, а __isset() - для свойств класса.

-1
ответ дан Matt 28 August 2018 в 11:48
поделиться

простыми словами, __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()

4
ответ дан Mohammed Al Ashaal 28 August 2018 в 11:48
поделиться

В чем разница между общими функциями 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: перегрузка с некоторыми изменениями.

Надеюсь, это поможет!

1
ответ дан N Moeini 28 August 2018 в 11:48
поделиться

Прежде всего позвольте мне рассказать вам, что делает функция 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";
?>
5
ответ дан Utkarsh Singh 28 August 2018 в 11:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: