我需要了解魔法函数__isset()
和普通函数isset()
。实际上php语言构造isset()
和php魔术方法__isset()
之间的真正区别是什么?当我谷歌时,他们告诉我__isset()
是一个神奇的功能。常见的php函数和php中的魔术函数有什么区别?
答案 0 :(得分:43)
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()
结果无论如何都会automatically casted为bool
。
实际上你可以定义自定义函数__isset()
,但它与魔术方法无关。
请参阅this example。
与通用函数不同,只能在类作用域中定义,并且可以在特定事件上自动调用,例如:不可访问的方法调用,类序列化,在不可访问的属性上使用unset()
等等。另请参阅此官方文档:Overloading。
答案 1 :(得分:5)
__ 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魔法。
答案 2 :(得分:5)
首先让我告诉你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";
?>
答案 3 :(得分:4)
简单来说, __ isset()帮助isset()处理类中的受保护/私有变量。
示例:强>
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 :(得分:1)
当某些事情发生时,会自动调用(触发)魔术函数。必须通过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
答案 5 :(得分:1)
常见的php函数和php中的魔术函数有什么区别?
通过预期的输入和结果声明和访问公共PHP函数,但应该调用它们。相比之下,魔术函数是在PHP中定义的,但是当在类中定义时,它们将被自动调用。例如,isset()
是PHP function
确定变量是否已设置且不是NULL
但是__isset()是一个类的Property overloading。
PHP中的重载提供了动态创建&#34;的方法。属性和方法。这些动态实体通过魔术方法处理,可以在类中为各种动作类型建立。 在与尚未声明或在当前作用域中不可见的属性或方法交互时,将调用重载方法。
如果在类中声明,它将在场景后面神奇地调用。让我们试验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
它说隐藏了&#39;未设置属性并显示bool(false)
,但回显值&#39; 2&#39;后来因为隐藏了#39;属性在课堂外不可见,它会调用__isset()
魔术函数,但它也没有设置在&#39;数据&#39;所以它返回bool(false)
。在getHidden()
函数中虽然它返回了对象私有属性&#39; hidden&#39;对象内部函数可见。在最后var_dump($obj->hidden)
中,它调用__get()
方法并返回NULL。因为在__get()
方法中,它会查找data['hidden']
的{{1}}。
注意:此处的示例来自PHP Manuel: Overloading并进行了一些修改。
希望这有帮助!
答案 6 :(得分:-1)
isset()
用于变量,__isset()
用于类的属性。