php get instance of,PHP instanceof 使用注意事项

在查看laravel源码的时候,看到有如下一段代码:

/**

* Get the registered service provider instance if it exists.

*

* @param \Illuminate\Support\ServiceProvider|string $provider

* @return \Illuminate\Support\ServiceProvider|null

*/

public function getProvider($provider)

{

$name = is_string($provider) ? $provider : get_class($provider);

return Arr::first($this->serviceProviders, function ($key, $value) use ($name) {

return $value instanceof $name;

});

}

当时就有点困惑,然后在tinker连就敲了一下验证,结果陷入更大的迷惑中。。。

下棉代码是这个问题的尝试的心路历程:

>>> use App\Model\Account;

=> null

>>> $account = new Account();

=> App\Model\Account {#1607}

>>> $account instanceof 'App\Model\Account';

PHP Parse error: Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING on line 1

>>> $account instanceof App\Model\Account;

=> true

>>> $a = 'abc';

=> "abc"

>>> $a instanceof 'abc';

PHP Parse error: Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING on line 1

>>> $account instanceof 'App\Model\Account';

PHP Parse error: Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING on line 1

>>> get_class($a);

PHP warning: get_class() expects parameter 1 to be object, string given on line 1

>>> get_class($account);

=> "App\Model\Account"

>>> $name = get_class($account);

=> "App\Model\Account"

>>> $account instanceof $name;

=> true

>>> gettype($name);

=> "string"

>>> $account instanceof "App\Model\Account";

PHP Parse error: Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING on line 1

>>> $account instanceof Account;

=> true

>>> $temp = "App\Model\Account";

=> "App\Model\Account"

>>> $account instanceof $temp;

=> true

其实上面问题的核心是instanceof的用法问题,在网上已经有这样的讨论,我将其粘贴出来:

class MyClass {

public $bar;

public function __construct() {

$this->bar = "Hello World";

}

public function foo() {

return $this->bar;

}

}

$a = new MyClass;

$b = new MyClass;

if($a instanceof get_class($b)) {

echo "Is instance";

} else {

echo "Is NOT instance";

}

//输出

Parse error: syntax error, unexpected '(' in /usercode/file.php on line 19

但是如果,你这样改写:

$x = get_class($b);

if($a instanceof $x) {

echo "Is instance";

} else {

echo "Is NOT instance";

}

//输出

Is instance

答案是因为instanceof并不是函数,只能接受对象(字面量的,不是字符串)或者变量。如果后面接的是函数或者是字符串(字面量的),那肯定是会报错的,本身语法就会有问题。

原讨论的回答如下:

Logically that would be the case, and if instanceof were a function then it would be the actual case. However, instanceof is a language construct operator, not a normal function and for that reason it doesn't play by the same rules.

instanceof does not accept expressions like a normal function would, and because calling a function like get_class is an expression you can't use it with instanceof.

instanceof accepts only two types of arguments. Either a class name (literal, not as a string) or a variable containing a string that is the class name.

Other language constructs like empty and isset function in exactly the same fashion (ie: you can't pass an expression to them either).

Note that you can use the is_a() function if you want to pass the class name as an expression.

参考网站:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值