Подтвердить что ты не робот

В чем разница между isset() и __isset()?

Мне нужно знать о магической функции __isset() и нормальной функции isset(). На самом деле, какова реальная разница между конструкцией языка php isset() и магическим методом php __isset()? Когда я google, они сказали, что __isset() - волшебная функция. В чем разница между общими функциями php и магическими функциями в php?

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

Прежде всего позвольте мне рассказать вам, что делает функция 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 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";
?>

Ответ 4

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

Ответ 5

Магические функции автоматически вызывается (срабатывает), когда что-то происходит. Нормальные функции должны быть специально вызваны вашим PHP-кодом.

В вашем случае: __isset() будет автоматически вызываться, если у вас есть isset(), который пытается получить не доступное свойство.

Пример:

[email protected]:/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);

[email protected]:/tmp/php# php a.php 
__isset invoked for att1

Ответ 6

В чем разница между обычными 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 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 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), но выдает значение "2" позже, потому что свойство "hidden" не отображается вне класса и вызывает магическую функцию __isset(), но оно также не задано в 'data', поэтому возвращает bool(false). В функции getHidden(), хотя она возвращает закрытое свойство объекта, которое видимо для внутренних объектов объекта. В последнем var_dump($obj->hidden) он вызывает метод __get() и возвращает NULL. Потому что в методе __get() он ищет data['hidden'], который NULL.

Примечание: здесь приведен пример из PHP Manuel: Перегрузка с некоторыми изменениями.

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

Ответ 7

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