【问题标题】:How to validate console command prompt inputs如何验证控制台命令提示符输入
【发布时间】:2017-06-08 03:56:49
【问题描述】:

在我提示输入的控制台命令之后。我想验证用户输入。我该怎么做?

我已经检查了this plugin。但它看起来像验证参数和选项。不是交互式输入。

CreateClient.php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class CreateClient extends Command {
    ...

    public function handle() {
        $name   = $this->ask('Enter name ');
        $email  = $this->ask('Enter email ');
        $date   = $this->ask('Enter date [Eg: 2016-01-01 00:00:00] ');

        // Validate user input
        $this->info('Validating user inputs');

       // How to validate email & date format ?
    }
}

更新

是的,我知道Validator,但担心的是验证会停止用户旅程。用户从头开始重新启动。是否可以为每个问题附加验证,因此验证将立即并提示再次输入。

以下是我在不输入任何值时注意到的情况,我想知道如何提供更多的验证规则。

提前致谢。

【问题讨论】:

    标签: laravel validation command laravel-5.4


    【解决方案1】:

    下面是另一种使用 Laravel 的验证器的方法。

    我的自定义方法validate_cmd 需要2个参数:

    1. 作为匿名函数的Command 方法(询问、秘密、选择...)
    2. 规则数组

    如果验证失败,将再次调用Command 方法。

    当然,你会想把它放在一个 Trait 中。

    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use Validator;
    
    class CreateClient extends Command {
    
        public function handle() {
    
            $name = $this->validate_cmd(function() {
                return $this->ask('Enter name');
            }, ['name','required']);
    
            $email = $this->validate_cmd(function() {
                return $this->ask('Enter email');
            }, ['email','required|email']);
    
            $date = $this->validate_cmd(function() {
                return $this->ask('Enter date [Eg: 2016-01-01 00:00:00]');
            }, ['date','required']);
    
        }
    
        /**
         * Validate an input.
         *
         * @param  mixed   $method
         * @param  array   $rules
         * @return string
         */
        public function validate_cmd($method, $rules)
        {
            $value = $method();
            $validate = $this->validateInput($rules, $value);
    
            if ($validate !== true) {
                $this->warn($validate);
                $value = $this->validate_cmd($method, $rules);
            }
            return $value;
        }
    
        public function validateInput($rules, $value)
        {
    
            $validator = Validator::make([$rules[0] => $value], [ $rules[0] => $rules[1] ]);
    
            if ($validator->fails()) {
                $error = $validator->errors();
                return $error->first($rules[0]);
            }else{
                return true;
            }
    
        }
    
    }
    

    【讨论】:

    • 感谢您的意见。我发布了我的解决方案,请看一下
    【解决方案2】:

    一种方法是使用FILTER_VALIDATE_EMAILCarbon

    public function handle() {
        $name   = $this->ask('Enter name ');
        $email  = $this->ask('Enter email ');
        $date   = $this->ask('Enter date [Eg: 2016-01-01 00:00:00] ');
    
        // Validate user input
        $this->info('Validating user inputs');
    
        // How to validate email & date format ?
        $email_status = filter_var($email, FILTER_VALIDATE_EMAIL);
    
        if (!$email_status) {
            // Invalid EMAIL
        }
    
        if (\Carbon::createFromFormat('YOUR DATE FORMAT', $date) === false) {
            // Invalid date
        }
    
    }
    

    另一种方法是@btl 使用Validator 所说的

    public function handle() {
        $name   = $this->ask('Enter name ');
        $email  = $this->ask('Enter email ');
        $date   = $this->ask('Enter date [Eg: 2016-01-01 00:00:00] ');
    
        // Validate user input
        $this->info('Validating user inputs');
    
        $data = array(
            'email' => $email,
            'date'  => $date
        );
    
        $rules = array(
            'email' => 'required|email',
            'date'  => 'required|date',
        );
    
        $validator = \Validator::make($data, $rules);
    
        if ($validator->fails()) {
            $messages = $validator->messages();
        }
    
    }
    

    【讨论】:

    • 感谢您的建议。我期待更多的是当用户输入无效的电子邮件时,它会立即返回错误。对此的担忧是用户必须输入所有输入然后才意识到验证失败。
    【解决方案3】:

    创建一个验证器实例并设置相应的规则。

    https://laravel.com/api/5.4/Illuminate/Contracts/Validation/Validator.html

    具体见 make() 方法。

    https://laravel.com/api/5.4/Illuminate/Contracts/Validation/Factory.html

    public function handle()
    {
        $name = $this->ask('Enter name ');
        $validator = \Validator::make(['name' => $name], ['name' => 'required|string']);
        if ($validator->fails()) {
            $message = $validator->messages();
        }
        $email = $this->ask('Enter email ');
        $validator = \Validator::make(['email' => $email], ['email' => 'required|email']);
        if ($validator->fails()) {
            $message = $validator->messages();
        }
        $date = $this->ask('Enter date [Eg: 2016-01-01 00:00:00] ');
        $validator = \Validator::make(['date' => $date], ['date' => 'required|datetime']);
        if ($validator->fails()) {
            $message = $validator->messages();
        }
    
        // so something with $message
    }
    

    【讨论】:

    • 感谢您的建议。我期待更多的是当用户输入无效的电子邮件时,它会立即返回错误。对此的关注是用户必须输入所有输入然后意识到验证失败。很抱歉没有把问题说清楚
    • 没有什么能阻止您在每个输入之间进行验证。询问->验证->询问->验证....等等。
    • 是的,好点,但旅程就停在那里。它不会再次提示问题。我更新了问题
    【解决方案4】:

    我就是这样解决的。

    由于\Symfony\Component\Console\Style\SymfonyStyle类支持将验证回调作为第三个参数传递,我编写了一个下面的函数并调用它。

    /**
     * Prompt the user for input.
     *
     * @param  string $question
     * @param  string $default
     * @param  callable|null $validator
     * @return string
     */
    public function askWithValidation($question, $default = null, $validator = null)
    {
        return $this->output->ask($question, $default, $validator);
    }
    

    通用验证函数

    use Validator;
    
    /**
     * Validates the user input
     *
     * @param string $attribute
     * @param string $validation
     * @param string $value
     * @throws Exception
     * @return string
     */
    protected function validateInput(string $attribute, string $validation, $value)
    {
        if (! is_array($value) && ! is_bool($value) && 0 === strlen($value)) {
            throw new \Exception('A value is required.');
        }
    
        $validator = Validator::make([
            $attribute => $value
        ], [
            $attribute => $validation
        ]);
    
        if ($validator->fails()) {
            throw new \Exception($validator->errors()->first($attribute));
        }
    
        return $value;
    }
    

    致电:

    $contactEmail = $this->askWithValidation('Enter contact email ', null, function ($value) {
        return $this->validateInput('contactEmail', 'email', $value);
    });
    

    【讨论】:

      【解决方案5】:

      这是Erevald 的略微修改版本,因为我也需要类似的功能。

      public function validate_console($method, $rules)
      {
          $value = $method();
          $validate = $this->validateInput($rules, $value);
      
          if ($validate !== true) {
              $messages = collect($validate->messages())->flatten()->all();
              foreach ($messages as $failure) {
                  $this->warn($failure);
              }
              $value = $this->validate_console($method, $rules);
          }
          return $value;
      }
      
      public function validateInput($rules, $value)
      {
          $validator = Validator::make([key($rules) => $value], $rules);
          if ($validator->fails()) {
              return $validator->errors();
          }else{
              return true;
          }
      }
      

      用法:

      $client_name = $this->validate_console(function() {
              return $this->ask('What should I call you? (Client Name)');
          }, ['client_name' => 'email|min:4']);
      

      输出:

      The client name must be a valid email address.
      The client name must be at least 4 characters.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-18
        • 2017-08-23
        • 1970-01-01
        • 2014-02-21
        • 1970-01-01
        • 2011-06-15
        • 2020-03-03
        • 1970-01-01
        相关资源
        最近更新 更多