Laravel ORM 关系 returns 数据库中不存在值时出错

Laravel ORM relationship returns error when value not present in DB

我在查询关系时遇到问题。 我正在查询项目、公司和产品之间的关系。但是,只要数据库中不存在项目 ID,就会发生致命异常:

Call to a member function companies() on a non-object

public function index($i) {
    return $this->returnTop($i, Array(
        'projectid' => 5,
        'products' => Array(1, 2, 3)
        )
    );
}

public function returnTop($count = 6, $args = Array()) {
    $companies = Project::find($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
        $q->whereIn('products.id', $args['products']);
    })->with('products')->limit($count)->get();

    return Response::json($companies);
}

现在,我知道数据库中不存在项目 ID 5,这很可能是导致此错误的原因,但我想 return 一条消息而不是应用程序抛出致命错误错误....

有什么想法吗?

只需检查 find() returns null。像这样:

$project = Project::find($args['projectid']);
if(is_null($project)){
    return Response::json(['message' => 'Project not found']);
}
$companies = $project->companies()->whereHas('products', function($q) use($args) {
    $q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();

return Response::json($companies);

另一种方法是 findOrFail,它会抛出 ModelNotFoundException。您可以全局处理异常或在控制器中捕获它:

try {

    $companies = Project::findOrFail($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
        $q->whereIn('products.id', $args['products']);
    })->with('products')->limit($count)->get();

    return Response::json($companies);

} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e){
    return Response::json(['message' => 'Project not found']);
}

您首先必须测试返回的对象是否真的不为空。盲目地假设数据库查询成功是在等待 sh*t 击中风扇。

public function returnTop($count = 6, $args = Array()) {
    $project = Project::find($args['projectid']);
    if($project) {
        $companies = $project->companies()->whereHas('products', function($q) use($args) {
            $q->whereIn('products.id', $args['products']);
        })->with('products')->limit($count)->get();

        return Response::json($companies);
    }
    else {
        return; // .. your error or whatever
    }
}

此外 "call to a member function on a non-object" 非常具体,它告诉您无法调用方法(成员函数),因为您正试图在非对象上调用它。