我正在使用 Laravel 5 的命令总线,但不清楚如何实现验证器类

Posted

技术标签:

【中文标题】我正在使用 Laravel 5 的命令总线,但不清楚如何实现验证器类【英文标题】:I am using Laravel 5's Command Bus and I am unclear how to implement a validator class 【发布时间】:2015-07-09 12:31:33 【问题描述】:

我正在使用Laravel 5's Command Bus,但不清楚如何实现验证器类。

我想创建一个 ResizeImageCommandValidator 类,在尝试调整图像大小之前检查图像是否真的是图像。

我想从 ResizeImageCommandHandler resize 方法中提取的代码在这里。

if (!($image instanceof Image))

    throw new ImageInvalidException('ResizeImageCommandHandler');

这个想法来自 Laracasts Commands and Domain Events,但 Jeffrey 没有使用 Laravel 5 架构。

这是代码。

ResizeImageCommandHandler.php

<?php namespace App\Handlers\Commands;

use App\Commands\ResizeImageCommand;

use App\Exceptions\ImageInvalidException;
use Illuminate\Queue\InteractsWithQueue;
use Intervention\Image\Image;

class ResizeImageCommandHandler 

    /**
     * Create the command handler.
     */
    public function __construct()
    
    
    /**
     * Handle the command.
     *
     * @param  ResizeImageCommand  $command
     * @return void
     */
    public function handle($command)
    
        $this->resizeImage($command->image, $command->dimension);
    
    /**
     * Resize the image by width, designed for square image only
     * @param Image $image Image to resize
     * @param $dimension
     * @throws ImageInvalidException
     */
    private function resizeImage(&$image, $dimension)
    
        if (!($image instanceof Image))
        
            throw new ImageInvalidException('ResizeImageCommandHandler');
        
        $image->resize($dimension, null, $this->constrainAspectRatio());
    
    /**
     * @return callable
     */
    private function constrainAspectRatio()
    
        return function ($constraint) 
            $constraint->aspectRatio();
        ;
    


      

ResizeImageCommand.php

<?php namespace App\Commands;

use App\Commands\Command;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use Image;

class ResizeImageCommand extends Command 
    use InteractsWithQueue, SerializesModels;

    public $image;
    public $savePath;
    public $dimension;

    /**
     * Create a new command instance.
     * @param Image $image
     * @param string $savePath
     * @param int $dimension
     * @param int $pose_id
     * @param int $state_id
     */
    public function __construct(&$image, $savePath, $dimension)
    
        $this->image = $image;
        $this->savePath = $savePath;
        $this->dimension = $dimension;
    


【问题讨论】:

只是质疑,我也不确定。为什么不在规则中使用使用 mime 的请求? laravel.com/docs/5.0/validation#rule-mimes @borracciaBlu 我正在通过引用传递一个 Image 实例,以便我可以调整它的大小。我需要验证我发送的对象是否属于该类型,以便我可以在其上调用图像调整大小。此时它没有 mime 类型,因为它是原生 php 资源。 那么为什么不在 $image 上使用类型提示呢? 如果它是我想要检查的唯一东西,那会起作用,但我希望最终有一个更好的控制级别,然后只是一个需要验证器的 Image 对象。我的示例已被简化,但它也可以检查以确保要调整大小的图像具有特定的尺寸和类型。这段代码按原样工作,我只是想清理它。 【参考方案1】:

您可以使用 Laravel 5 的 FormRequest 类在您的请求发送到命令总线之前捕获它:

public function postResizeImage(ResizeImageRequest $request) 
    // Send request to the Command Bus

然后在您的ResizeImageRequest 类中,输入规则,您可能需要自定义验证来验证上传的文件是否实际上是图像。

您可以使用https://packagist.org/packages/intervention/image 处理图像文件。或者你可以使用这个https://github.com/cviebrock/image-validator

问我是否需要进一步的帮助

【讨论】:

我相信有一个装饰器模式,但我不清楚它是如何实现的。我真的不想为内置的东西使用包。 您可以在这里轻松学习装饰器模式:laracasts.com/lessons/the-decorator-pattern @whoacowboy 它不是装饰器。这是一个简单的方法注入。它将表单请求对象注入到您的控制器方法中,该方法将在您的控制器代码处理您的请求之前自动验证您的请求laravel.com/docs/master/validation#form-request-validation【参考方案2】:

为了回答您的问题,我建议不要过于关注它的 Command 部分。在 Laravel 5.1 中,该文件夹被重命名为“Jobs”——参考;

https://laravel-news.com/2015/04/laravel-5-1/

这正是因为泰勒觉得人们过于拘泥于“命令”这个词。

另见http://www.laravelpodcast.com/episodes/6823-episode-21-commands-pipelines-and-packages和https://laracasts.com/lessons/laravel-5-commands

Illuminate 包中的验证器类非常棒,http://laravel.com/api/5.0/Illuminate/Validation/Validator.html - 我想我不确定这是什么问题。

我会说,除非您有令人信服的理由为此使用 Command 类,否则不要这样做。另见:http://www.laravelpodcast.com/episodes/9313-episode-23-new-beginnings-envoyer-laravel-5-1

我谦虚地建议你可能问错了问题,也许你不需要使用命令来处理这个问题。

这可能是您正在寻找的答案:https://mattstauffer.co/blog/laravel-5.0-validateswhenresolved

use Illuminate\Contracts\Validation\ValidatesWhenResolved;

如果这不起作用,请注册 Larachat,http://larachat.co/ - 一个 Slack 频道,专门处理这类事情。 Laravel 帮助的最佳场所。 (当然 Stack Overflow 除外)

这是我用来检查图像格式的一个小类,我认为你可能会发现它很有用。

<?php
Class FileUploadFormat

public function is_image($image_path)
  
      if (!$f = fopen($image_path, 'rb'))
      
          return false;
      

      $data = fread($f, 8);
      fclose($f);

      // signature checking
      $unpacked = unpack("H12", $data);
      if (array_pop($unpacked) == '474946383961' || array_pop($unpacked) == '474946383761') return "gif";
      $unpacked = unpack("H4", $data);
      if (array_pop($unpacked) == 'ffd8') return "jpg";
      $unpacked = unpack("H16", $data);
      if (array_pop($unpacked) == '89504e470d0a1a0a') return "png";
      return false;
  

【讨论】:

还有;至于图像处理包,我强烈推荐:packagist.org/packages/league/glide 感谢您的回答。无论名称(命令或作业)如何,我都在寻找验证在此命令中发送的数据的最佳方法。写完这篇文章后,我意识到图像可能不是案例研究。我会查看马特的帖子,看看它是如何工作的。 我认为:mattstauffer.co/blog/… - 是你想要的。

以上是关于我正在使用 Laravel 5 的命令总线,但不清楚如何实现验证器类的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5 – 清除共享主机服务器中的缓存

Laravel Artisan Migrate 命令创建表但不将每个迁移文件填充到迁移表

Laravel 5 - 重定向到 HTTPS

获取数组中对象的编号,但不获取对象本身。 - Laravel 5.2

基本 JS 文件加载但不渲染或执行 Laravel 8 Bootstrap 5

Laravel 更新密码通过验证但不更新记录