覆盖Laravel MessageBag时出现问题
我的目标是: 我们正在开发一个API,我们需要自定义错误消息,不仅要发送自定义字符串,还要发送cusotm代码。 例如:自定义无效电子邮件错误消息应如下所示:覆盖Laravel MessageBag时出现问题,laravel,Laravel,我的目标是: 我们正在开发一个API,我们需要自定义错误消息,不仅要发送自定义字符串,还要发送cusotm代码。 例如:自定义无效电子邮件错误消息应如下所示: error[ 'code' => 102, 'message' => 'invalid email' ] 我可以将这些自定义错误消息设置为数组,但我对电子邮件有问题 我得到: 第248行的illumb\Support\MessageBag中的“数组到字符串转换”。 之所以这样,是因为它需要一个字符串,而现在我有了一个数组
error[
'code' => 102,
'message' => 'invalid email'
]
我可以将这些自定义错误消息设置为数组,但我对电子邮件有问题
我得到:
第248行的illumb\Support\MessageBag中的“数组到字符串转换”。
之所以这样,是因为它需要一个字符串,而现在我有了一个数组
protected function transform($messages, $format, $messageKey)
{
return collect((array) $messages)
->map(function ($message) use ($format, $messageKey) {
// We will simply spin through the given messages and transform each one
// replacing the :message place holder with the real message allowing
// the messages to be easily formatted to each developer's desires.
return str_replace([':message', ':key'], [$message, $messageKey], $format);
})->all();
}
我想用以下内容覆盖(绑定)此方法:
protected function transform($messages, $format, $messageKey)
{
return collect((array) $messages)
->map(function ($message) use ($format, $messageKey) {
if(is_array($message)){
$message = json_encode($message);
}
// We will simply spin through the given messages and transform each one
// replacing the :message place holder with the real message allowing
// the messages to be easily formatted to each developer's desires.
return str_replace([':message', ':key'], [$message, $messageKey], $format);
})->all();
}
我已经完成了以下步骤。
我已经创建了Libraries/Extensions/MessagesBag文件夹,并在那里放置了以下文件
MessageBagServiceProvider.php
namespace App\Libraries\Extensions\MessageBag;
use Illuminate\Support\ServiceProvider;
class MessageBagServiceProvider extends ServiceProvider{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bind('Illuminate\Support\MessageBag', 'App\Libraries\Extensions\MessageBag\YcoMessageBag');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('messagebag');
}
}
messagebagafacade.php
namespace App\Libraries\Extensions\MessageBag;
use Illuminate\Support\Facades\Facade as IlluminateFacade;
class MessageBagFacade extends IlluminateFacade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'messagebag'; }
}
YcoMessagebag.php
namespace App\Libraries\Extensions\MessageBag;
use Illuminate\Support\MessageBag as OriginalMessageBag;
class YcoMessageBag extends OriginalMessageBag{
/**
* Format an array of messages.
*
* @param array $messages
* @param string $format
* @param string $messageKey
* @return array
*/
protected function transform($messages, $format, $messageKey)
{
return collect((array) $messages)
->map(function ($message) use ($format, $messageKey) {
if(is_array($message)){
$message = json_encode($message);
}
// We will simply spin through the given messages and transform each one
// replacing the :message place holder with the real message allowing
// the messages to be easily formatted to each developer's desires.
return str_replace([':message', ':key'], [$message, $messageKey], $format);
})->all();
}
}
我已经在config/app.php中注册了我的MessageBagServiceprodider.php
App\Libraries\Extensions\MessageBag\MessageBagServiceProvider::class,
当我死了并在MessageBagServiceProvider的注册方法中转储时,它工作了,代码死了并转储了“hello”
但是MessageBag类没有被覆盖,仍然加载了原始类。
我试着和你一起玩
$this->app->bind('Illuminate\Support\MessageBag', 'App\Libraries\Extensions\MessageBag\YcoMessageBag');
我试过:$this->app->singleton,
我尝试使用\illumb\Support\MessageBag访问原始类,也尝试了使用'\App\Libraries\Extensions\MessageBag\YcoMessageBag',但没有成功。
我可以重写这个类吗?解决办法是什么
谢谢大家! 我已经找到了答案,下面是我的解决方案: 我已经创建了Exteptions/Handler.php
class Handler extends ExceptionHandler
{
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException) {
return $this->convertValidationExceptionToResponse($exception, $request);
} elseif ($exception instanceof ModelNotFoundException) {
$modelName = strtolower(class_basename($exception->getModel()));
return $this->errorResponse(
'Does not exists any ' . $modelName . ' with this id',
Response::HTTP_NOT_FOUND
);
} elseif ($exception instanceof AuthenticationException) {
return $this->unauthenticated($request, $exception);
} elseif ($exception instanceof AuthorizationException) {
return $this->errorResponse($exception->getMessage(), Response::HTTP_FORBIDDEN);
} elseif ($exception instanceof MethodNotAllowedHttpException) {
return $this->errorResponse('The specified request is invalid!', Response::HTTP_METHOD_NOT_ALLOWED);
} elseif ($exception instanceof NotFoundHttpException) {
return $this->errorResponse('The specified url cannot be found!', Response::HTTP_NOT_FOUND);
} elseif ($exception instanceof HttpException) {
$message = $exception->getMessage();
$status = $exception->getStatusCode();
$httpStatusCodes = collect(Response::$statusTexts);
if (!$httpStatusCodes->has($status)) {
$status = Response::HTTP_UNPROCESSABLE_ENTITY;
}
if ($message == "") {
$message = "An error occured when processing request!";
}
return $this->errorResponse($message, $status);
}
return parent::render($request, $exception);
}
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
return $this->errorResponse('Unauthenticated', Response::HTTP_UNAUTHORIZED);
}
/**
* Create a response object from the given validation exception.
*
* @param \Illuminate\Validation\ValidationException $e
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function convertValidationExceptionToResponse(ValidationException $e, $request)
{
$errors = $e->validator->errors()->getMessages();
$errors = $this->convertValidationErrors($errors);
return response()->json([
'success' => false,
'error' => $errors,
'status' => 422,
'message' => $e->getMessage()
], 422);
}
protected function convertValidationErrors($errors){
$codes = [
101 => [
'code'=> 101,
'message'=> 'A mező kitöltése kötelező'
],
106=>[
'code'=> 106,
'message'=> 'A mező tartalma nem elég hosszú'
],
102 =>[
'code'=> 102,
'message'=> 'A mező tartalma nem elég hosszú'
],
103 => [
'code'=> 103,
'message'=> 'A mező tartalma túl hosszú'
],
105 => [
'code'=> 105,
'message'=> ' A mező tartalma nem szöveg'
],
107 => [
'code'=> 107,
'message'=> 'Formátum nem megfelelő'
],
104 => [
'code'=> 104,
'message'=> 'Az email formátuma nem megfelelő'
],
];
foreach($errors as $key => $code){
if(isset($codes[$code[0]])) {
unset($errors[$key][0]);
$errors[$key]['code'] = $codes[$code[0]]['code'];
if(env('APP_ENV') != 'local') {
$errors[$key]['message'] = $codes[$code[0]]['message'];
}
}
}
return $errors;
}
}
也许不是最漂亮的解决方案,但它很有效。我已经找到了答案,以下是我的解决方案: 我已经创建了Exteptions/Handler.php
class Handler extends ExceptionHandler
{
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException) {
return $this->convertValidationExceptionToResponse($exception, $request);
} elseif ($exception instanceof ModelNotFoundException) {
$modelName = strtolower(class_basename($exception->getModel()));
return $this->errorResponse(
'Does not exists any ' . $modelName . ' with this id',
Response::HTTP_NOT_FOUND
);
} elseif ($exception instanceof AuthenticationException) {
return $this->unauthenticated($request, $exception);
} elseif ($exception instanceof AuthorizationException) {
return $this->errorResponse($exception->getMessage(), Response::HTTP_FORBIDDEN);
} elseif ($exception instanceof MethodNotAllowedHttpException) {
return $this->errorResponse('The specified request is invalid!', Response::HTTP_METHOD_NOT_ALLOWED);
} elseif ($exception instanceof NotFoundHttpException) {
return $this->errorResponse('The specified url cannot be found!', Response::HTTP_NOT_FOUND);
} elseif ($exception instanceof HttpException) {
$message = $exception->getMessage();
$status = $exception->getStatusCode();
$httpStatusCodes = collect(Response::$statusTexts);
if (!$httpStatusCodes->has($status)) {
$status = Response::HTTP_UNPROCESSABLE_ENTITY;
}
if ($message == "") {
$message = "An error occured when processing request!";
}
return $this->errorResponse($message, $status);
}
return parent::render($request, $exception);
}
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
return $this->errorResponse('Unauthenticated', Response::HTTP_UNAUTHORIZED);
}
/**
* Create a response object from the given validation exception.
*
* @param \Illuminate\Validation\ValidationException $e
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function convertValidationExceptionToResponse(ValidationException $e, $request)
{
$errors = $e->validator->errors()->getMessages();
$errors = $this->convertValidationErrors($errors);
return response()->json([
'success' => false,
'error' => $errors,
'status' => 422,
'message' => $e->getMessage()
], 422);
}
protected function convertValidationErrors($errors){
$codes = [
101 => [
'code'=> 101,
'message'=> 'A mező kitöltése kötelező'
],
106=>[
'code'=> 106,
'message'=> 'A mező tartalma nem elég hosszú'
],
102 =>[
'code'=> 102,
'message'=> 'A mező tartalma nem elég hosszú'
],
103 => [
'code'=> 103,
'message'=> 'A mező tartalma túl hosszú'
],
105 => [
'code'=> 105,
'message'=> ' A mező tartalma nem szöveg'
],
107 => [
'code'=> 107,
'message'=> 'Formátum nem megfelelő'
],
104 => [
'code'=> 104,
'message'=> 'Az email formátuma nem megfelelő'
],
];
foreach($errors as $key => $code){
if(isset($codes[$code[0]])) {
unset($errors[$key][0]);
$errors[$key]['code'] = $codes[$code[0]]['code'];
if(env('APP_ENV') != 'local') {
$errors[$key]['message'] = $codes[$code[0]]['message'];
}
}
}
return $errors;
}
}
也许不是最漂亮的解决方案,但它是有效的。该类不是从容器中解析的。需要
MessageBag
s的地方,如验证器,调用newmessagebag
,因此没有与容器交互来解决该问题。@lagbox谢谢,现在它有意义了。我想我可以覆盖任何这样的核心类。这个类不是从容器中解析出来的。需要MessageBag
s的地方,如验证器,调用newmessagebag
,因此没有与容器交互来解决该问题。@lagbox谢谢,现在它有意义了。我想我可以覆盖任何这样的核心类。