覆盖Laravel MessageBag时出现问题

覆盖Laravel MessageBag时出现问题,laravel,Laravel,我的目标是: 我们正在开发一个API,我们需要自定义错误消息,不仅要发送自定义字符串,还要发送cusotm代码。 例如:自定义无效电子邮件错误消息应如下所示: error[ 'code' => 102, 'message' => 'invalid email' ] 我可以将这些自定义错误消息设置为数组,但我对电子邮件有问题 我得到: 第248行的illumb\Support\MessageBag中的“数组到字符串转换”。 之所以这样,是因为它需要一个字符串,而现在我有了一个数组

我的目标是: 我们正在开发一个API,我们需要自定义错误消息,不仅要发送自定义字符串,还要发送cusotm代码。 例如:自定义无效电子邮件错误消息应如下所示:

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谢谢,现在它有意义了。我想我可以覆盖任何这样的核心类。