php Laravel 检查约束违规
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26363271/
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
Laravel check for constraint violation
提问by guidsen
I was curious if there is a way we can check if there is a constraint violation error when delete or insert a record into the database.
我很好奇是否有一种方法可以检查在删除或向数据库中插入记录时是否存在约束冲突错误。
The exception thrown is called 'QueryException' but this can be a wide range of errors. Would be nice if we can check in the exception what the specific error is.
抛出的异常称为“QueryException”,但这可能是范围广泛的错误。如果我们可以在异常中检查特定错误是什么,那就太好了。
回答by Razor
You are looking for the 23000 Error code (Integrity Constraint Violation)
. If you take a look at QueryException
class, it extends from PDOException
, so you can access to $errorInfo
variable.
您正在寻找23000 Error code (Integrity Constraint Violation)
. 如果您查看QueryException
class,它从 扩展PDOException
,因此您可以访问$errorInfo
变量。
To catch this error, you may try:
要捕获此错误,您可以尝试:
try {
// ...
} catch (\Illuminate\Database\QueryException $e) {
var_dump($e->errorInfo);
}
// Example output from MySQL
array (size=3)
0 => string '23000' (length=5)
1 => int 1452
2 => string 'Cannot add or update a child row: a foreign key constraint fails (...)'
To be more specific (Duplicate entry, not null, add/update child row, delete parent row...), it depends on each DBMS:
更具体地说(重复条目,不为空,添加/更新子行,删除父行...),这取决于每个 DBMS:
- PostgreSQLand SQL serverfollow the SQL standard's conventions for
SQLSTATE
code, so you may return the first value from the array$e->errorInfo[0]
or call$e->getCode()
directly - MySQL, MariaDBand SQLitedo not strictly obey the rules, so you need to return the second value from the array
$e->errorInfo[1]
- PostgreSQL和SQL Server遵循 SQL 标准的
SQLSTATE
代码约定,因此您可以从数组中返回第一个值$e->errorInfo[0]
或$e->getCode()
直接调用 - MySQL、MariaDB和SQLite不严格遵守规则,因此您需要从数组中返回第二个值
$e->errorInfo[1]
For laravel, handling errors is easy, just add this code in your "app/start/global.php" file ( or create a service provider):
对于laravel,处理错误很容易,只需在“app/start/global.php”文件中添加以下代码(或创建一个服务提供者):
App::error(function(\Illuminate\Database\QueryException $exception)
{
$error = $exception->errorInfo;
// add your business logic
});
回答by Ahmed Mahmoud
first put this in your controller
首先把它放在你的控制器中
use Exception;
second handle the error by using try catch like this example
第二个通过使用 try catch 像这个例子一样处理错误
try{ //here trying to update email and phone in db which are unique values
DB::table('users')
->where('role_id',1)
->update($edit);
return redirect("admin/update_profile")
->with('update','update');
}catch(Exception $e){
//if email or phone exist before in db redirect with error messages
return redirect()->back()->with('phone_email','phone_email_exist before');
}
New updates here without need to use try catchyou can easily do that in validation rules as the following code blew
此处的新更新无需使用try catch,您可以在验证规则中轻松做到这一点,因为以下代码爆炸了
public function update(Request $request, $id)
{
$profile = request()->all();
$rules = [
'name' => 'required|unique:users,id,'.$id,
'email' => 'required|email|unique:users,id,'.$id,
'phone' => 'required|unique:users,id,'.$id,
];
$validator = Validator::make($profile,$rules);
if ($validator->fails()){
return redirect()->back()->withInput($profile)->withErrors($validator);
}else{
if(!empty($profile['password'])){
$save['password'] = bcrypt($profile['password']);
}
$save['name'] = $profile['name'];
$save['email'] = $profile['email'];
$save['phone'] = $profile['phone'];
$save['remember_token'] = $profile['_token'];
$save['updated_at'] = Carbon::now();
DB::table('users')->where('id',$id)->update($save);
return redirect()->back()->with('update','update');
}
}
where id related to record which you edit.
其中 id 与您编辑的记录相关。
回答by Sam Wong
You may also try
你也可以试试
try {
...
} catch ( \Exception $e) {
var_dump($e->errorInfo );
}
then look for error code.
然后查找错误代码。
This catches all exception including QueryException
这会捕获所有异常,包括 QueryException
回答by geoandri
回答by Patrick.SE
If you are using Laravel version 5
and want global exception handling of specific cases you should put your code in the report
method of the /app/Exception/Handler.php
file. Here is an example of how we do it in one of our micro services:
如果您使用 Laravelversion 5
并希望对特定情况进行全局异常处理,则应将代码放在文件的report
方法中/app/Exception/Handler.php
。以下是我们如何在我们的一项微服务中执行此操作的示例:
public function render($request, Exception $e)
{
$response = app()->make(\App\Support\Response::class);
$details = $this->details($e);
$shouldRenderHttp = $details['statusCode'] >= 500 && config('app.env') !== 'production';
if($shouldRenderHttp) {
return parent::render($request, $e);
}
return $response->setStatusCode($details['statusCode'])->withMessage($details['message']);
}
protected function details(Exception $e) : array
{
// We will give Error 500 if we cannot detect the error from the exception
$statusCode = 500;
$message = $e->getMessage();
if (method_exists($e, 'getStatusCode')) { // Not all Exceptions have a http status code
$statusCode = $e->getStatusCode();
}
if($e instanceof ModelNotFoundException) {
$statusCode = 404;
}
else if($e instanceof QueryException) {
$statusCode = 406;
$integrityConstraintViolation = 1451;
if ($e->errorInfo[1] == $integrityConstraintViolation) {
$message = "Cannot proceed with query, it is referenced by other records in the database.";
\Log::info($e->errorInfo[2]);
}
else {
$message = 'Could not execute query: ' . $e->errorInfo[2];
\Log::error($message);
}
}
elseif ($e instanceof NotFoundHttpException) {
$message = "Url does not exist.";
}
return compact('statusCode', 'message');
}
The Response
class we use is a simple wrapper of Symfony\Component\HttpFoundation\Response as HttpResponse
which returns HTTP responses in a way that better suits us.
Response
我们使用的类是一个简单的包装器,Symfony\Component\HttpFoundation\Response as HttpResponse
它以更适合我们的方式返回 HTTP 响应。
Have a look at the documentation, it is straightforward.
看一下文档,很简单。