【问题标题】:laravel eloquent foreach loop error Trying to get property 'location_id' of non-objectlaravel 雄辩的 foreach 循环错误尝试获取非对象的属性'location_id'
【发布时间】:2021-12-31 13:01:42
【问题描述】:

这件事以前发生在我身上,但我不知道为什么以及如何避免它。所以我在模型中有一个静态函数,它获取所有数据库行并使用 foreach 循环读取另一个表,但我无法正确读取行数据:

    public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            $map      = AccountMap::where( 'account_id', $account->id )->first();
            $location = Location::getLocation( $map->location_id );
            $data     = $location->getData();
        }
    }

所以上面的函数收集了一个项目数组($accounts),然后将其传递到一个 foreach 循环中,到目前为止一切都很好,但是如果我现在使用 $account->id 它是空的。 id 显示在其属性文件夹中的 Account 对象中。

在此模型的其他地方使用了一个非常相似的函数,但它使用传递的 id 并且这个函数有效(但是 $account->id 为空)。问题不在于数据库或列名:

    public static function getThisLocation( $id )
    {
        $account = self::find( $id );
        $map     = AccountMap::where( 'account_id', $id )->first();
        location = Location::getLocation( $map->location_id );
        $data    = $location->getData();

        return $data;

    }

*** 编辑 *** Account、AccountMap 和 Location 都是 Eloquent 模型

namespace App\Models;
use Eloquent;
use App\Notifications\AccountMessages;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Notifications\Notifiable;

/**
 * @method static find(int $id)
 */
class Account extends Eloquent
{
    use Sortable;
    use Notifiable;

public $sortable = [
        'id',
        'name',
        'lastupdate',
        'url'
    ];

public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            $map      = AccountMap::where( 'account_id', $account->id )->first();
            $location = Location::getLocation( $map->location_id );
            $data     = $location->getData();
        }
    }

    public static function getThisLocation( $id )
    {
        $account = self::find( $id );
        $map     = AccountMap::where( 'account_id', $id )->first();
        location = Location::getLocation( $map->location_id );
        $data    = $location->getData();

        return $data;

    }

}
namespace App\Models;

use Eloquent;
use Kyslik\ColumnSortable\Sortable;

/**
 * @method static where(string $string, int $id)
 */
class AccountMap extends Eloquent
{
    use Sortable;

    public $sortable = [
        'id',
        'account_id',
        'location'
    ];

}

*** 更多编辑 *** 我已经确认使用 $account->attributes['id'] 有效,但我不知道为什么我期望的工作没有($account->id)

【问题讨论】:

  • 所以$map 不是一个对象。因此$map = AccountMap::where( 'account_id', $account->id )->first(); 要么不返回一个对象,要么它没有返回任何东西
  • 问题是 $account->id 返回 null,所以 $map 找不到数据
  • 我们在这里讨论的是哪个版本?因为我认为应该是extends Model,它最终甚至可能会回答最近更新的问题...

标签: php eloquent


【解决方案1】:

问题一定与模型的通信和迁移有关。

将此 dd() 添加到您当前的测试函数中:

 public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            if ($account->id){
                $map      = AccountMap::where( 'account_id', $account->id )->first();
                $location = Location::getLocation( $map->location_id );
                $data     = $location->getData();
            } else {
             dd($account)
            }
        }
    }

然后检查结果,看看您的回复中是否有 id 文件?如果不是,则您自己的模型上不存在 id 字段,这是您的问题的原因。

最后,使用以下命令轻松检查您的模型字段:

 public function testReturnOfSelfModel()
    {
        $data= self::all();
        dd($data);
    }

如果你在这个 dd 函数上有 id,你的模型工作正常。如果没有,你没有 id 字段。

此外,更改模型的第一个字符大写更专业。它应该是自我,而不是自我。

【讨论】:

  • 所有的模型在这个测试中都是雄辩的。我在问题中提到该模型具有一个数组属性,其中包含列项(即看起来 $account->attributes['id'] 可以工作,但肯定这应该与 $account->id 一起工作吗?跨度>
  • 它应该可以工作。你有没有像我说的那样用 dd($account) 重新运行 test() ?如果是的话,把答案放在这里看看
  • 嗨 Mohammad,结果是一个包含 100 行 Account 模型的数组,每行都有一个属性数组,它还有其他字段,包括 id。尽管 id 存在于属性数组中,但它在对象本身中设置为 null。但为什么会这样呢?我的其他雄辩模型是正确的并且如预期的那样 ($map = AccountMap::where( 'account_id', 5 )->first(); echo $map->location_id;) 在这种情况下返回 5。我在上面发布了 Account 模型。
【解决方案2】:

我建议设置两个正确的数据Model(迁移需要创建这些表):

class Account extends Model {

    protected $table = 'accounts';

    public $timestamps = false;

    /**
     * The attributes that are mass assignable.
     * @var array
     */
    protected $fillable = [];

    /**
     * The attributes that should be hidden for arrays.
     * @var array
     */
    protected $hidden = [];

}

除非定义protected $table,否则它肯定不知道该怎么做。

还不清楚您甚至想用AcountMap 完成什么,但它可能需要定义一个关系;例如。使用return $this->belongsTo(Account::class); ...而只需将latlng 添加到class Account 将远没有那么复杂且完全没问题,而它只有1 个location

【讨论】:

  • 我同意这可以做得更好并且可以添加外键。这只是我在其他项目中遇到的概念测试。使用上面的代码似乎通过这个简单的测试打破了模型。如果我添加 id,我能够正确地从数据库中获取数据,数据已经迁移/播种,这个测试项目在分页表中显示这些结果。为简洁起见,我省略了控制器和视图。数据在称为属性的对象中返回数组中的行,而不是作为对象返回。 $model->id 不起作用,但 $model->attributes['id'] 起作用,这不是预期的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多