【问题标题】:How can I avoid validating user input 3 times - on the form javascript, in the controller and in the model如何避免验证用户输入 3 次 - 在表单 javascript、控制器和模型中
【发布时间】:2014-11-20 01:50:12
【问题描述】:

在不到处重复代码的情况下验证用户数据的最佳方法是什么?现在,我必须在 3 个不同的地方编写验证代码。

我必须在 Javascript 中验证数据以提供实时验证 - 这不是一封有效的电子邮件,该电子邮件正在使用中! 这是由一些 Javascript 执行的页面上的代码。

我必须验证控制器中的数据以确保数据有效 - 这不是一封有效的电子邮件!这是由管理已发布数据的“表单”对象完成的。它的字段具有验证器,并确保它们都通过验证。

最后,我必须在模型中验证以确保数据是唯一的(有时) - 该电子邮件正在使用中! 这是在模型中完成的,因为不应该使用表单对象访问数据库以获取此类信息。

我在这里做什么?

我正在使用 Phalcon,以防模型验证器的东西看起来很奇怪(Phalcon 似乎是这样设置的)

【问题讨论】:

    标签: forms validation phalcon


    【解决方案1】:

    您必须决定在哪里验证数据。你应该有2个位置。首先是用户端。但我想你已经知道了——永远不要相信用户端。所以你必须在服务器端重新验证它。只要决定你在哪里做。您可以在 Model 中执行此操作,您可以在 Controller 中执行此操作,但要在任何地方执行此操作 - 这不应该发生。

    在用户端,您可以使用默认的 html5 输入 type="email",它将验证用户是否输入了电子邮件。

    我的最后一个策略是使用验证插件,它可以验证所有输入。

    我的插件是这样的:

    <?php
    //namespace App\Plugins;
    
    use Phalcon\Validation,
        Phalcon\Validation\Validator\Email,
        Phalcon\Validation\Validator\Url,
        Phalcon\Validation\Validator\StringLength;
    
    class ValidateInput
    {
        public function validate_field($field_name, $value)
        {
            $field_name = strtolower($field_name);
            $method = 'validate_' . $field_name;
            if (method_exists($this, $method)) {
                return $this->$method($value);
            }
            error_log('#d5s4f5s method "' . $method . '" does not exist. Please create one.');
            return false;
        }
    
        private function validate_name($value)
        {
            $value = trim($value);
            if (!preg_match('~^(?:[\p{L}\p{Mn}\p{Pd}\'\x{2019}\s.]+)+$~u', $value) > 0) {
                return false;
            }
            return true;
        }
    
        private function validate_ssl($value)
        {
            if (in_array($value, array('0', '1'))) {
                return true;
            }
            return false;
        }
        .....
    

    然后是来自用户端的任何东西我通过这个调用(来自控制器):

    public function loginAction()
    {
        try {
            $this->validateInput(array('app_token', 'email', 'password', 'client_ip'));
    
            .....
    

    我所有的控制器都在扩展 BaseController,它有这个功能(称为 1 行):

    /*
         * Check var from request
         */
        public function validateInput($fields)
        {
            foreach ($fields as $field) {
                if ($this->request->get($field) === null) {
                    $error_hint = "Add '$field' to your request.'";
                    throw new Exception($this->make_api_error('#g654f', 'MISSING_INPUT_' . strtoupper($field), $error_hint));
                } else {
                    $validation_result = $this->validate_input->validate_field($field, $this->request->get($field));
                    if (!$validation_result) {
                        $error_hint = "Value of '$field' is invalid.";
                        if ($field == 'password') {
                            $error_hint .= ' Password must be from 7 to 50 characters in length.';
                        } else {
                            $error_hint .= ' Value submitted: ' . $this->request->get($field) . '.';
                        }
                        if ($field == 'app_token') {
                            $error_hint .= ' Contact us if your app token is not working.';
                        }
                        throw new Exception($this->make_api_error('#g3456', 'INVALID_INPUT_' . strtoupper($field), $error_hint));
                    }
                }
            }
            return;
        }
    

    就是这样。我现在知道,我可以在任何需要的地方使用所有这些变量。如果它无效,则脚本已返回有关输入的错误响应。我可以在我的模型、控制器或任何地方使用它,因为所有操作的第一行是验证所有输入。每个字段都经过验证。

    【讨论】:

      猜你喜欢
      • 2013-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      相关资源
      最近更新 更多