Laravel 控制器模型的豁免处理结构与数据库事务

至于架构,哪一个是丢弃从模型到控制器的例外时的良好做法?

结构A.

:

UserController.php


public function updateUserInfo/UserInfoRequest $request, UserModel $userModel/
{
$isError = false;
$message = 'Success';

try {
$message = $userModel->updateUserInfo/$request->only/['username', 'password']//;
} catch /SomeCustomException $e/ {
$isError = true;
$message = $e->getMessage//;
}

return json_encode/[
'isError' => $isError,
'message' => $message
]/;
}


UserModel.php


public function updateUserInfo/$request/
{
$isError = false;
$message = 'Success';

$username = $request['username'];
$password = $request['password'];

try {
$this->connect//->beginTransaction//;

$this->connect//->table/'users'/->where/'username', $username/->update/['password' => $password]/;

$this->connect//->commit//;
} catch /\Exception $e/ {
$this->connect//->rollback//;
$isError = true;
$message = $e->getMessage//;
}

return [
'isError' => $isError,
'message' => $message
];
}


结构 B

:

UserController.php


public function updateUserInfo/UserInfoRequest $request, UserModel $userModel/
{
$isError = false;
$message = 'Success';

try {
$userModel->updateUserInfo/$request->only/['username', 'password']//;
} catch /SomeCustomException $e/ {
$isError = true;
$message = $e->getMessage//;
} catch /QueryException $e/ {
$isError = true;
$message = $e->getMessage//;
}

return json_encode/[
'isError' => $isError,
'message' => $message
]/;
}


UserModel.php


public function updateUserInfo/$request/
{
$username = $request['username'];
$password = $request['password'];

try {
$this->connect//->beginTransaction//;

$this->connect//->table/'users'/->where/'username', $username/->update/['password' => $password]/;

$this->connect//->commit//;
} catch /\Exception $e/ {
$this->connect//->rollback//;
throw new QueryException//;
}
}




结构A.

模型捕获任何异常,回滚事务并返回控制器如果出现错误或者不是。 然后,控制器只需返回从模型返回的所有内容。

而在

结构 B

该模型捕获了任何异常,回滚交易,然后抛出 QueryException, 如果发生异常。 然后控制器捕获被遗弃 QueryException 从模型中,如果它有错误或者不是,则返回它。

原因

结构体 B

它仍然有一个抓住,所以在这是应该回滚的模型。 如果我删除了 try-catch 这里的模型是控制器在此,要直接捕获异常,将在控制器上处理回滚,在此,它看起来,稍微关闭控制器的功能。

让我知道你的想法。
谢!
已邀请:

冰洋

赞同来自:

为什么我认为这种方法 B 它更好:

您的模型应仅包含逻辑部分:这包括与数据库的通信 /交易和召回/, 和

不是

格式化要打印用户的错误消息。

保持模型清洁:这是结构中最重要的部分。 MVC. 如果你破坏了一切,那么发现任何错误都很难。

外包错误处理:如果将其放在控制器中,则可以选择在那里处理它 /您可能需要此方法的一些特殊格式化输出,或者您需要其他一些要调用的功能。/ 或者你处理它
App\Exceptions\Handler

. 在这种情况下,您可以在此处显示此错误消息,并且您无需在控制器中执行此操作。

因此,如果您不需要任何特殊功能,并且您想要使用所有电源 Laravel, 我会建议你

结构体 C

UserController.php


public function updateUserInfo/UserInfoRequest $request, UserModel $userModel/
{
$userModel->updateUserInfo/$request->only/['username', 'password']//;
return response//->json/['message' => 'updated user.']/;
}


UserModel.php


public function updateUserInfo/$request/
{
$username = $request['username'];
$password = $request['password'];
try {
$this->connect//->beginTransaction//;

$this->connect//->table/'users'/->where/'username', $username/->update/['password' => $password]/;

$this->connect//->commit//;
} catch /\Exception $e/ {
$this->connect//->rollback//;
throw new QueryException//;
}
}


App\Exceptions\Handler


public function render/$request, Exception $exception/
{
//catch everything what you want
if /$exception instanceof CustomException/ {
return response//->json/[
'message' => $exception->getMessage//
], 422/;
}

return parent::render/$request, $exception/;
}


您有纯粹的数据库材料分离。 /模型/, 介绍材料 /控制器/ 和错误处理 /处理程序/. 结构 C 允许您在其他函数中重用错误处理,在另一个控制器功能中具有相同的情况。

这是我的意见,但是当你认为这种方法不是最好的解决方案时,我将讨论任何情景。

风见雨下

赞同来自:

首先

, 对于您的示例,您甚至不需要使用交易。 您只执行一个请求。 那你为什么回滚? 你想回滚什么样的查询? 当您需要完全处理的更改时,应使用该交易以读取完成并有效的操作。 如果第一个是成功的,但下面的任何一个都有任何错误,你可以回滚一切,就好像什么都没有完成。

其次,让我们继续致力于良好做法或最佳实践的问题。

Laravel 提供薄的控制器和厚模型。 因此,您的整个业务逻辑应该在存储库中甚至更好。 控制器将充当经纪人。 它将从存储库或模型收集数据,并将它们传输到视图。

除了

多哥, laravel 为组织您的代码提供了一种良好和便捷的方法。 您可以使用
Event


Observers

对于模型中的并行工作。

最佳实践取决于用户的知识和经验。 所以,谁知道你的问题的最佳答案仍在领先。

莫问

赞同来自:

我希望控制器和系统的任何其他部分,它与模型相互作用,尽可能多地相对于模型的内部工作。 所以,例如,我会尽量不实现
QueryException

s 在模型之外,而是将其视为一个简单的对象 PHP, 什么时候有可能。

此外,我会利用用户响应结构 JSON 并使用
https://httpstatuses.com/
HTTP . 如果它有意义,那么用户信息更新路由可能返回更新的资源,并且可能就足够了
200 OK

.


// UserModel.php
public function updateUserInfo/$request/
{
$username = $request['username'];
$password = $request['password'];

try {
$this->connect//->beginTransaction//;

$this->connect//->table/'users'/->where/'username', $username/->update/['password' => $password]/;

$this->connect//->commit//;

return $this->connect//->table/'users'/->where/'username', $username/->first//;
// or just return true;
} catch /\Exception $e/ {
$this->connect//->rollback//;

return false;
}
}

// UserController.php
public function updateUserInfo/UserInfoRequest $request, UserModel $userModel/
{
$updated = $userModel->updateUserInfo/$request->only/['username', 'password']//;

if /$updated/ {
return response/$updated/;
// HTTP 200 response. Returns JSON of updated user.
// Alternatively,
// return response/''/;
// /200 OK response, no content/
} else {
return response/'optional message', 422/;
// 422 or any other status code that makes more sense in the situation.
}


/绝对不是主题,我认为这是一个例子,但在我提醒你不要存储简单的文本密码。/

詹大官人

赞同来自:

我不明白为什么你没有看杰弗里课,而是为了更新用户,你不需要一个部分 try/catch.
您是控制器方法:


public function update/UpdateUserRequest $request, User $user/ : JsonResponse
{
return response//->json/$user->update/$request->all////
}


您请求规则方法:


public function rules//: array
{
return [
'username' => 'required|string',
'password' => 'required|min:6|confirmed',
];
}


你是一个例外处理程序。渲染方法:


public function render/$request, Exception $exception/
{
if /$request->ajax// || $request->wantsJson/// {
$exception = $this->prepareException/$exception/;

if /$exception instanceof \Illuminate\Http\Exception\HttpResponseException/ {
return $exception->getResponse//;
} elseif /$exception instanceof \Illuminate\Auth\AuthenticationException/ {
return $this->unauthenticated/$request, $exception/;
} elseif /$exception instanceof \Illuminate\Validation\ValidationException/ {
return $this->convertValidationExceptionToResponse/$exception, $request/;
}

// we prepare custom response for other situation such as modelnotfound
$response = [];
$response['error'] = $exception->getMessage//;

if /config/'app.debug'// {
$response['trace'] = $exception->getTrace//;
$response['code'] = $exception->getCode//;
}

// we look for assigned status code if there isn't we assign 500
$statusCode = method_exists/$exception, 'getStatusCode'/
? $exception->getStatusCode//
: 500;

return response//->json/$response, $statusCode/;
}
return parent::render/$request, $exception/;
}


现在,如果你有一个例外, Laravel 会给你B. Json 使用状态代码 != 200, 否则,将赋予成功的结果!

要回复问题请先登录注册