LARAVEL:当ID为非Integer时,如何引起404错误而不是50x错误
我在Laravel中创建了一个简单的CRUD,但是我有一个问题:
我正在使用Illuminate \ support \ authate \ route ::资源方法,这是我的路由/web.php:app/http/http/controllers/notecontroller.php:php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/', function () {
return Inertia::render('Welcome', [
'canLogin' => Route::has('login'),
'canRegister' => Route::has('register'),
'laravelVersion' => Application::VERSION,
'phpVersion' => PHP_VERSION,
]);
});
Route::get('dashboard', [App\Http\Controllers\PageController::class, 'dashboard'])
->middleware('auth:sanctum')
->name('dashboard');
Route::resource('notes', App\Http\Controllers\NoteController::class)
->middleware('auth:sanctum');
:
<?php
namespace App\Http\Controllers;
use App\Models\Note;
use Illuminate\Http\Request;
use Inertia\Inertia;
class NoteController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if ($request->q) {
return Inertia::render('Notes/Index', [
'notes' => Note::where('title', 'ilike', "%$request->q%")->get(),
]);
}
return Inertia::render('Notes/Index', [
'notes' => Note::all()
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return Inertia::render('Notes/Create', [
'note' => new Note()
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$note = Note::create($request->validate([
'title' => 'required',
'content' => 'required',
]));
return redirect()->route('notes.show', $note)->with('success', 'Nota creada');
}
/**
* Display the specified resource.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function show(Note $note)
{
return Inertia::render('Notes/Show', compact('note'));
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function edit(Note $note)
{
return Inertia::render('Notes/Edit', compact('note'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Note $note)
{
$request->validate([
'title' => 'required',
'content' => 'required',
]);
$note->update($request->all());
return redirect()->route('notes.show', $note)->with('success', 'Nota actualizada');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function destroy(Note $note)
{
$note->delete();
return redirect()->route('notes.index')->with('success', 'Nota eliminada');
}
}
当我转到 /notes /a时,“ a”应该是我想看的注释的索引,我会收到500个错误:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type bigint: "a"
select *从“注释”中select * where“ id” = a limit 1
此时,我的代码尚未运行。如何捕获此错误以提出404错误?
I created a simple crud in Laravel, but I'm having a problem:
I am using Illuminate\Support\Facades\Route::resource method, this is my routes/web.php:
<?php
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/', function () {
return Inertia::render('Welcome', [
'canLogin' => Route::has('login'),
'canRegister' => Route::has('register'),
'laravelVersion' => Application::VERSION,
'phpVersion' => PHP_VERSION,
]);
});
Route::get('dashboard', [App\Http\Controllers\PageController::class, 'dashboard'])
->middleware('auth:sanctum')
->name('dashboard');
Route::resource('notes', App\Http\Controllers\NoteController::class)
->middleware('auth:sanctum');
app/Http/Controllers/NoteController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Note;
use Illuminate\Http\Request;
use Inertia\Inertia;
class NoteController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if ($request->q) {
return Inertia::render('Notes/Index', [
'notes' => Note::where('title', 'ilike', "%$request->q%")->get(),
]);
}
return Inertia::render('Notes/Index', [
'notes' => Note::all()
]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return Inertia::render('Notes/Create', [
'note' => new Note()
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$note = Note::create($request->validate([
'title' => 'required',
'content' => 'required',
]));
return redirect()->route('notes.show', $note)->with('success', 'Nota creada');
}
/**
* Display the specified resource.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function show(Note $note)
{
return Inertia::render('Notes/Show', compact('note'));
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function edit(Note $note)
{
return Inertia::render('Notes/Edit', compact('note'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Note $note)
{
$request->validate([
'title' => 'required',
'content' => 'required',
]);
$note->update($request->all());
return redirect()->route('notes.show', $note)->with('success', 'Nota actualizada');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Note $note
* @return \Illuminate\Http\Response
*/
public function destroy(Note $note)
{
$note->delete();
return redirect()->route('notes.index')->with('success', 'Nota eliminada');
}
}
When I go to /notes/a where 'a' is supposed to be the index of the note I want to see, I get a 500 error:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type bigint: "a"
select * from "notes" where "id" = a limit 1
At this point, none of my code has yet run. How can I catch this error to raise a 404 error instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于您使用内置资源控制器,因此将创建以下URI,并发生模型绑定。如果参数不适合ID类型,则会出错。
当模型绑定发生时,我尚未找到修改请求验证的方法。如果您想自定义行为,则可以通过将
show
和编辑
函数从“路由资源声明”中删除,并编写上面列出的自定义端点。ROUTES/web.php
App/http/controllers/notecontroller.php
您可以通过将
请求
切换到继承formrequest
的自定义请求来执行验证。可以在此处找到更多信息:
https://laravel.com/docs/docs/9.x/validation#形式重新验证
Since you're using the built-in resource controller, the following URIs, among others, will have been created and model binding happens. If the parameter doesn't fit the id's type it will error out.
I have not found a way to modify the request validation when model binding happens. If you wish to customise the behaviour, you can do so by leaving the
show
andedit
functions out of the route resource declaration and writing custom endpoints listed above.routes/web.php
app/Http/Controllers/NoteController.php
You can perform the validation by switching
Request
to a custom request which inheritsFormRequest
.More information can be found here:
https://laravel.com/docs/9.x/validation#form-request-validation
路线模型绑定在MySQL/Mariadb上一直有效,但是不在postgres 上 。基于泰勒的“ nofollow noreferrer”> comment修复它。因此,解决方案就是这样:
等。
更新且优化的路由文件将看起来像这样:
Route model binding has worked as you expect forever on MySQL/MariaDB but does not on Postgres. Based on Taylor's comment in the issue, they don't seem interested in fixing it. So the solution is something like this:
etc.
An updated and optimized route file would look like this:
您可以在下面使用firstorfail()或FindorFail示例代码
you can use firstOrFail() or findOrFail example code below
如果找不到数据,则可以使用中止代码的流产(404)。
You can use abort(404) which abort your code if no data found.