新网创想网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍升级php7后isset方法始终为 false怎么办,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
创新互联专注于辛集企业网站建设,成都响应式网站建设公司,商城系统网站开发。辛集网站建设公司,为辛集等地区提供建站服务。全流程按需网站设计,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务公司升级 php7 后出现了一个问题,类似这样 isset($post->user->name)
始终为 false
,之前的php 5.6 就很正常,laravel 版本是 5.1.35(很久没升级了)。
先看看isset
isset
用来检测变量是否设置
首先我们来看官方的一个例子
大致上是下面这个意思
'foobar']; public function __get($key) { if (isset($this->attributes[$key])) { return $this->attributes[$key]; } } } $post = new Post(); echo isset($post->content); // false
上面这个例子将永远返回 false
,因为 foo
并不是 Post
的属性,而是 __get
取出来的
魔术方法 __isset
那么怎么解决上面那个问题呢?使用魔术方法
'foobar']; public function __get($key) { if (isset($this->attributes[$key])) { return $this->attributes[$key]; } } public function __isset($key) { if (isset($this->attributes[$key])) { return true; } return false; } } $post = new Post(); echo isset($post->content); //true
类似 Eloquent
的例子
看着 laravel 5.1.35 的代码,我们自己写一个简单的例子
先有一个 Model
,简单的实现。__get
,__set
,__isset
class Model { // 存放属性 protected $attributes = []; // 存放关系 protected $relations = []; public function __get($key) { if( isset($this->attributes[$key]) ) { return $this->attributes[$key]; } // 找到关联的对象,放在关系里面 if (method_exists($this, $key)) { $relation = $this->$method(); return $this->relations[$method] = $relation; } } public function __set($k, $v) { $this->attributes[$k] = $v; } public function __isset($key) { if (isset($this->attributes[$key]) || isset($this->relations[$key])) { return true; } return false; } }
然后我们定义一个 Post Moel
和一个 User Moel
class Post extends Model { protected function user() { $user = new User(); $user->name = 'user name'; return $user; } } class User extends Model { }
好了来验证一下isset
$post = new Post(); echo 'isset 发帖用户:'; echo isset($post->user) ? 'true' : 'false'; // false echo PHP_EOL; echo 'isset 发帖用户的名字:'; echo isset($post->user->name) ? 'true' : 'false'; // false echo PHP_EOL; echo '发帖用户的名字:'; echo $post->user->name; // user name echo PHP_EOL; echo '再次判断 isset 发帖用户的名字:'; echo isset($post->user->name) ? 'true' : 'false'; // true echo PHP_EOL;
答案
分析上面的结果,感觉像是 php 7 isset
方法对对象的判断有了变化,如果先执行一次,$post->user->name
,也就是将 user 放在 post
的 relations
中,这样 isset($post->user)
为 true
,随后 isset($post->user->name)
才为 true
。
最后在 Eloquent model
的 git log
中 找到了答案,
PHP 7 has fixed a bug with __isset which affects both the native isset and empty methods. This causes specific issues with checking isset or empty on relations in Eloquent. In PHP 7 checking if a property exists on an unloaded relation, for example isset($this->relation->id) is always returning false because unlike PHP 5.6, PHP 7 is now checking the offset of each attribute before chaining to the next one. In PHP 5.6 it would eager load the relation without checking the offset. This change brings back the intended behavior of the core Eloquent model __isset method for PHP 7 so it works like it did in PHP 5.6. For reference, please check the following link, specifically Nikita Popov's comment (core PHP dev) - https://bugs.php.net/bug.php?id=69659
大致上是 php7 isset 判断的时候,会依次判断。php5.6 则会预加载关系。其实 laravel 也早就做了相关的处理,所以升级 laravel 后,自然也就没有这个问题了。
以上是升级php7后isset方法始终为 false怎么办的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注创新互联成都网站设计公司行业资讯频道!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。