php Laravel:在失败时处理 findOrFail()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32989034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:19:21  来源:igfitidea点击:

Laravel : Handle findOrFail( ) on Fail

phplaravellaravel-5.1

提问by cjmling

I am looking for something which can be like findOrDo(). Like do this when data not found. Something could be like

我正在寻找类似于 findOrDo() 的东西。像在找不到数据时这样做。事情可能像

Model::findOrDo($id,function(){
   return "Data not found";
});

Is there any similar thing in laravel that I can do this elegantly and beautifully ?

Laravel 中是否有类似的东西可以让我优雅而漂亮地做到这一点?

*I tried googling but could not find one

*我尝试谷歌搜索但找不到

回答by Meisam Mulla

use Illuminate\Database\Eloquent\ModelNotFoundException;

// Will return a ModelNotFoundException if no user with that id
try
{
    $user = User::findOrFail($id);
}
// catch(Exception $e) catch any exception
catch(ModelNotFoundException $e)
{
    dd(get_class_methods($e)); // lists all available methods for exception object
    dd($e);
}

回答by Pitchinnate

Another option is to modify the default Laravel Exception Handler, found in app/Exceptions/Handler.php on the render()function I made this change:

另一种选择是修改默认的 Laravel 异常处理程序,在 app/Exceptions/Handler.php 中找到render()我进行此更改的函数:

public function render($request, Exception $e)
{
    if(get_class($e) == "Illuminate\Database\Eloquent\ModelNotFoundException") {
        return (new Response('Model not found', 400));
    }
    return parent::render($request, $e);
}

That way instead of getting a 500, I send back a 400 with a custom message without having to do a try catch on every single findOrFail()

这样我就不会得到 500,而是用自定义消息发回 400,而不必对每个消息都进行尝试 findOrFail()

回答by thewizardguy

An alternative process could be to evaluate a collection instead. So,

替代过程可能是评估集合。所以,

$modelCollection = Model::where('id', $id)->get();
if(!$modelCollection->isEmpty()) {
    doActions();
}

I agree it isn't as elegant, a one-liner or as case specific as you or I might like, but aside from writing a try catch statement every time, it's a nice alternative.

我同意它不像您或我可能喜欢的那样优雅、单行或特定于案例,但除了每次编写 try catch 语句之外,它还是一个不错的选择。

回答by lasec0203

as of Laravel v5.7, you can do this (the retrieving single modelvariation of @thewizardguyanswer)

从 Laravel v5.7 开始,您可以执行此操作(@thewizardguy答案的检索单个模型变体)

// $model will be null if not found
$model = Model::where('id', $id)->first();

if($model) {
    doActions();
}

回答by Josh D.

By default, when you use an Eloquent model's findOrFailin a Laravel 5 application and it fails, it returns the following error:

默认情况下,当您findOrFail在 Laravel 5 应用程序中使用 Eloquent模型并失败时,它会返回以下错误:

ModelNotFoundException in Builder.php line 129:
'No query results for model [App\Model]'.

So to catch the exception and display a custom 404 page with your error message like "Ooops"....

因此,要捕获异常并显示带有错误消息的自定义 404 页面,例如“Ooops”....

Open up the app/Exceptions/Handler.phpfile, and add the code shown below to the top of the render function:

打开app/Exceptions/Handler.php文件,将下面显示的代码添加到渲染函数的顶部:

public function render($request, Exception $e)
{
   if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) 
   {
      abort(404, 'Oops...Not found!');
   }

   return parent::render($request, $e);
}

Source: https://selftaughtcoders.com/from-idea-to-launch/lesson-16/laravel-5-findorfail-modelnotfoundexception-show-404-error-page/

来源:https: //selftaughtcoders.com/from-idea-to-launch/lesson-16/laravel-5-findorfail-modelnotfoundexception-show-404-error-page/

回答by Romeo Sierra

A little later for the party, from laravel 5.4 onward, Eloquent Builder supports macros. So, I would write a macro (in a separate provider) like follows.

晚一点的聚会,从 laravel 5.4 开始,Eloquent Builder 支持宏。所以,我会写一个宏(在一个单独的提供者中),如下所示。

Builder::macro('firstOrElse', function($callback) {
   $res = $this->get();

   if($res->isEmpty()) {
       $callback->call($this);
   }

   return $res->first();
});

I can then do a retrieval as follows.

然后我可以按如下方式进行检索。

$firstMatchingStudent = DB::table('students')->where('name', $name)
    ->firstOrElse(function() use ($name) {
        throw new ModelNotFoundException("No student was found by the name $name");
    });

This will assign the first object of the result set if it is not empty, otherwise will adapt the behaviour I pass into the macro as a closure (throw Illuminate\Database\Eloquent\ModelNotFoundExceptionin this case).

如果结果集不为空,这将分配结果集的第一个对象,否则将调整我作为闭包传递给宏的行为(Illuminate\Database\Eloquent\ModelNotFoundException在这种情况下抛出)。

For the case of a model also this would work, except that models always return the builder instance.

对于模型的情况,这也可以工作,除了模型总是返回 builder instance