isset()和__isset()之间有什么区别?
我需要知道魔术函数__isset()
和正常函数isset()
。 其实什么是PHP语言构造isset()
和PHP魔法__isset()
之间的真正区别? 当我谷歌他们告诉__isset()
是一个神奇的function。 常见的PHP函数和php中的魔术函数有什么区别?
isset()
它是一个检查variables或类属性初始化的语言结构:
$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()
语言构造| 神奇的方法 | 总是返回布尔| 结果取决于定制逻辑* | 必须在代码|中被调用 事件自动调用 | 无限数量的参数| 只有一个参数 | 可以在任何范围内使用| 必须定义为方法** | 是一个保留关键字| 不是保留的关键字 | 无法重新定义(parsing错误)| 可以在扩展类中重新定义***
无论如何__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,并把任何对象视为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魔术方法。
首先让我告诉你什么isset()函数。 isset()函数检查值是否已设置或为空。 _ isset()函数是PHP中的一个神奇方法。 任何带有“_ ”的函数在PHP中都是一个神奇的方法。 现在,通过在不可访问的属性上调用isset()或empty()来调用__isset(),我指的是那些尚未在类中定义并且在运行时被明确定义的属性。 下面是一段代码,应该让你更好地理解它:
<?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()在类中的protected / private 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
被保护,你不能访问它,所以我们创build了__isset()
来帮助我们使用isset($x['key'])
你可以说__isset()
只是isset()
一个桥梁,
当发生某些事情时,魔术function会被自动调用(触发)。 正常的function必须由您的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函数是声明和访问预期的input和结果,但他们应该被调用。 相比之下,魔术function是在PHP中定义的,但是在类中定义时,它们将自动调用。 例如isset()
是一个PHP函数
确定是否设置了一个variables,而不是NULL
但__isset()是一个类的属性重载 。
PHP中的重载提供了dynamic“创build”属性和方法的方法。 这些dynamic实体通过魔术方法进行处理,可以在类中为各种动作typesbuild立。 与当前范围内尚未声明或不可见的属性或方法进行交互时,将调用重载方法。
如果在课堂上声明,它将在上面描述的场景中被神奇地称为。 让我们来试验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
它说隐藏的属性没有设置,并显示bool(false)
但回声值为'2'后,因为'隐藏'属性是不可见的类外,它调用__isset()
魔术function,但它也不设置'数据',所以它返回bool(false)
。 在getHidden()
函数中虽然返回对象内部函数可见的对象私有属性“hidden”。 在上一个var_dump($obj->hidden)
它调用__get()
方法,并返回NULL。 因为在__get()
方法中,它查找data['hidden']
,它是NULL
。
注意:这里的例子是从PHP曼努埃尔:重载与一些修改。
希望这可以帮助!
isset()
用于variables, __isset()
isset()
用于类的属性。