2

环境: PHP 7.3,Laravel 5.6

问题: empty()当代码在浏览器中isset()运行时返回错误的结果,但在 Tinker 命令行会话中运行时返回正确的结果。


预期行为:

  • isset()true当属性存在时返回,false当它不存在时
  • empty()true当属性存在和不存在时返回nullfalse否则

例子:empty()

if(!empty($practiceArea->hero_video)) { 
   ... some HTML
}

!empty总是评估为false,即使$practiceArea->hero_video已设置并且我可以通过echoor看到它的值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)返回。truefalsenull


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) "
4

1 回答 1

2

isset()非公共类属性需要在类中实现才能public function __isset()正常工作。

http://php.net/manual/en/language.oop5.overloading.php#object.isset

__isset()通过调用isset()empty()在不可访问的属性上触发。

您的具体问题来自 Laravel 中的实现:

public function __isset($key)
{
    return $this->offsetExists($key);
}

public function offsetExists($offset)
{
    return ! is_null($this->getAttribute($offset));
}

该方法getAttribute()不会检查所有类属性,并且会检查! is_null哪些不完全等同于isset()/empty()

https://github.com/laravel/framework/blob/5.6/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php

// If the attribute exists in the attribute array or has a "get" mutator we will
// get the attribute's value. Otherwise, we will proceed as if the developers
// are asking for a relationship's value. This covers both types of values.
if (array_key_exists($key, $this->attributes) ||
    $this->hasGetMutator($key)) {
    return $this->getAttributeValue($key);
}

我会尝试$attributes从该特征中调查属性的内容。

于 2019-03-19T15:51:17.200 回答