【发布时间】:2019-03-19 15:48:02
【问题描述】:
环境: PHP 7.3,Laravel 5.6
问题: empty() 和 isset() 在代码在浏览器中运行时返回不正确的结果,但在 Tinker 命令行会话中运行时返回正确的结果。
预期行为:
-
isset()在属性存在时返回true,在属性不存在时返回false -
empty()返回true当属性存在且不为null,否则返回false
示例:empty()
if(!empty($practiceArea->hero_video)) {
... some HTML
}
这个!empty 总是计算为false,即使设置了$practiceArea->hero_video 并且我可以通过echo 或var_dump 看到它的值。
而empty($practiceArea->hero_video) 总是评估为true,正如我在尝试替代方案失败后了解到的那样:
if(empty($practiceArea->hero_video) === false) {
示例:isset()
isset($practiceArea->hero_video) 总是错误地返回 false。
当前的 Hacky 解决方法:
$video = $practiceArea->hero_video;
if(!empty($video)) {
... some HTML
}
这完全符合预期 - $video 获取 $practiceArea->hero_video 的值,然后 !empty($video) 如果我们有值则返回 true,如果值为 false,则返回 false。
Tinker 会话中的预期结果示例:
>>> $pa = PracticeArea::find(11)
>>> ... an object is returned
>>> $pa->hero_video
=> "//www.youtube.com/embed/0qisGSwZym4"
>>> if(empty($pa->hero_video)) echo "Empty"; else echo "Not empty";
Not empty
>>> if(!empty($pa->hero_video)) echo "Not empty"; else echo "Empty";
Not empty
isset() 在 Tinker 中也可以正常工作:
>>> isset($pa->hero_video)
=> true
>>> !isset($pa->hero_video)
=> false
复制:
我假设我们的 PracticeArea 类正在使用魔法 getter,因为它扩展了 Laravel 5.6 的 Model 类,其中确实包括 __get 和 __isset 方法。
下面是删节的PracticeArea 类。很高兴发布整个内容,但没有与此相关的方法或属性。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use TCG\Voyager\Traits\Translatable;
class PracticeArea extends Model
{
protected $table = 'practice_areas';
}
var_dump($practiceAreas)
object(App\PracticeArea)#506 (29) {
["translatable":protected]=> array(5) {
[0]=> string(4) "name"
[1]=> string(11) "description"
[2]=> string(7) "heading"
[3]=> string(4) "body"
[4]=> string(4) "slug"
}
["table":protected]=> string(14) "practice_areas"
["fillable":protected]=> array(11) {
[0]=> string(25) "practice_area_category_id"
[1]=> string(11) "metadata_id"
[2]=> string(4) "name"
[3]=> string(11) "description"
[4]=> string(7) "heading"
[5]=> string(4) "body"
[6]=> string(10) "sort_order"
[7]=> string(9) "published"
[8]=> string(10) "hero_video"
[9]=> string(10) "hero_image"
[10]=> string(4) "slug"
}
["translates":protected]=> array(5) {
[0]=> string(4) "name"
[1]=> string(11) "description"
[2]=> string(7) "heading"
[3]=> string(4) "body"
[4]=> string(4) "slug"
}
["translate_relation":protected]=> string(14) "practice_areas"
["connection":protected]=> string(5) "mysql"
["primaryKey":protected]=> string(2) "id"
["keyType":protected]=> string(3) "int"
["incrementing"]=> bool(true)
["with":protected]=> array(0) { }
["withCount":protected]=> array(0) { }
["perPage":protected]=> int(15)
["exists"]=> bool(true)
["wasRecentlyCreated"]=> bool(false)
["attributes":protected]=> array(15) {
["id"]=> int(11)
["practice_area_category_id"]=> int(1)
["metadata_id"]=> int(26)
["name"]=> string(19) "Workplace Accidents"
["description"]=> string(30) "Workplace injuries description"
["heading"]=> string(30) "Workplace Accidents & Injuries"
["body"]=> string(1246) "
【问题讨论】:
-
出于兴趣,如果您创建了一个公共 get 方法并相应地使用 isset/empty 会发生什么?
-
虽然这可能是一个有趣的问题,尤其是环境之间的差异……如果
$video = $practiceArea->hero_video工作没有错误,即$practiceArea->hero_video保证不会引发任何关于未定义属性的错误(Eloquent 模型可能会,我有不知道...!?),那么您根本不需要也不应该使用empty或isset。 -
@treyBake 我将在今天晚些时候尝试并用结果更新帖子。
-
@deceze 在
hero_video为空的情况下,我们需要渲染一个不同的 HTML 块,它使用替代的hero_image。 -
所以,
isset/empty在有魔法吸气剂的类上需要类的合作才能正常工作。 Eloquent 似乎有问题,或者它假设您永远不需要将isset/empty与它的属性一起使用,因为它总是会为任何给定属性返回 a value 并且永远不会引发错误。那么你不应该使用isset/empty,而只是检查它的值,比如if (!$practiceArea->hero_video)。这将产生与您期望empty完全相同的效果。
标签: php laravel laravel-5 php-7.3