Codeigniter 表单验证 - 成功后如何取消设置表单值?

Posted

技术标签:

【中文标题】Codeigniter 表单验证 - 成功后如何取消设置表单值?【英文标题】:Codeigniter Form Validation - how to unset form values after success? 【发布时间】:2011-02-17 15:00:42 【问题描述】:

我意识到这个请求违反了 CI 文档中提供的示例(建议单独的“成功”页面视图),但我想在成功提交表单后重新使用给定的表单视图 - 显示成功消息然后显示一个空白表格。我尝试了几种方法未能成功清除验证集值(取消设置$_POST,将规则/字段设置为空数组并重新运行验证)。

我可以重定向到同一个页面,但是我必须设置一个会话变量来显示成功消息 - 这是一种混乱的方法。

任何想法如何最好地实现上述目标?

【问题讨论】:

取消设置帖子应该可以工作。你能发布一些代码 重定向到自身时会出现什么乱七八糟的情况? 【参考方案1】:

重定向到自身。这样一来,就没有运行任何提交...这也为您提供了一种显示 flash_data 的方法。

    $this->load->library('form_validation');

    $this->form_validation->set_rules('firstname', 'First Name', 'required');
    $this->form_validation->set_rules('surname', 'Sur Name', 'required');

    if ($this->form_validation->run() === TRUE)
    
                    // save data

        $this->session->set_flashdata('message', 'New Contact has been added');
        redirect(current_url());
    

    $this->load->view('contacts/add', $this->data);

【讨论】:

绝对是处理这个问题的最佳方法。 一直在寻找这个并认为这是唯一的方法......虽然我讨厌在会话中存储成功/错误消息。 非常感谢您的智慧之珠 :) 这个解决方案的不幸之处在于,如果重定向无法正确呈现,flashdata 将会丢失。必须为客户端编写一个回调代码,以主动确认用户收到了 flashdata,可能是通过来自渲染对话框的 AJAX 回调,尽管这仅限于与 JS 兼容的客户端。【参考方案2】:

另一种解决方案,扩展库CI_Form_validation$_field_data 的属性是受保护的,所以我们可以访问它:

class MY_Form_validation extends CI_Form_validation 

    public function __construct()
    
        parent::__construct();
    

    public function clear_field_data() 

        $this->_field_data = array();
        return $this;
    

并调用新方法。这样,您可以传递数据,而无需在会话中存储数据。

    class Item extends Controller
    
        function Item()
        
            parent::Controller();
        

        function add()
        
            $this->load->library('form_validation');
            $this->form_validation->set_rules('name', 'name', 'required');

            $success = false;

            if ($this->form_validation->run())
            
                $success = true;
                $this->form_validation->clear_field_data();
            

            $this->load->view('item/add', array('success' => $success));
        
    

【讨论】:

我认为这个比选择的答案要好得多,因为它在 CI 的范围内工作。它在本质上也非常可扩展,它扩展了非常 OOP 的 Form_validation 库。 CI 表单验证构造函数需要规则数组【参考方案3】:

将 TRUE/FALSE 变量传递给有条件地设置表单值的视图。

控制器

if($this->form_validation->run())

    $data['reset'] = TRUE;

else

    $data['reset'] = FALSE:


$this->load->view("form", $data);

观点:

<input type="text" name="email" value="<?php echo ($reset) ? "" : set_value('email'); ?>" />

<input type="text" name="first_name" value="<?php echo ($reset) ? "" : set_value('first_name'); ?>" />

【讨论】:

改用isset($reset),这样php就不会标记未定义变量错误。代码变为:value="&lt;?php echo isset($reset) ? "" : set_value('email'); ?&gt;"【参考方案4】:

set_value 函数从 Form_validation 对象而不是 $_POST 数组中获取其值。 Form_validation 对象将它自己的发布值副本存储在一个名为 $_field_data 的变量中。

这是一个 hack,但您可以在处理成功提交后清除此变量:

class Item extends Controller

    function Item()
    
        parent::Controller();
        $this->load->model('item_model');
    

    function add()
    
        $this->load->library('form_validation');
        $this->form_validation->set_rules('name', 'name', 'required');

        $success = false;

        if ($this->form_validation->run())
        
            $this->item_model->add_item($this->input->post('name'));
            $success = true;

            // Look away now. Hack coming up!
            // Clear the form validation field data
            $this->form_validation->_field_data = array();
        

        $this->load->view('item/add', array('success' => $success));
    

【讨论】:

你不需要“破解”任何东西。只需将其重定向到自身,这样就不会提交任何内容。 是的,这是显而易见的方法。但 OP 表示他不想这样做。 我在尝试将 _field_data 设置为空白数组时收到此错误:Fatal error: Cannot access protected property CI_Form_validation::$_field_data @kjones,我们不能直接访问这个变量。所以我们需要像***.com/a/14675189/1357033一样扩展这个库 这是受保护的财产,你不能这样做【参考方案5】:

希望这会有所帮助。最后我理解了扩展库的整个概念。您需要做的就是第 1 步:在此目录“application/libraries/”中,使用以下 php 代码创建一个名为“MY_Form_validation.php”的文件

<?php if (!defined('BASEPATH')) exit('No direct script access allowed.');
class MY_Form_validation extends CI_Form_validation 

 public function MY_Form_validation() 
    parent::__construct();
  

  public function unset_field_data()
        
        unset($this->_field_data);    
    

第 2 步: 然后在控制器中使用“unset_field_data()”功能。例如下面:

    if ($this->form_validation->run())
    
        $this->item_model->add_item($this->input->post('name'));
        $success = true;

        $this->form_validation->unset_field_data();
    

【讨论】:

【参考方案6】:

我发现在哪里:

    构成页面的 CI 视图部分不止一个,它们的控制器方法执行验证 自上次页面刷新以来,其中一个验证失败并产生错误,例如输入字段值的格式或键入错误

仅清除validation-rules数组是不够的,还需要清除validation-error数组。

为此,我在system/libraries/Form_Validation.php中添加了一个方法,如下:

public function clear_rules()

    $this->_error_array = array();
    $this->_field_data = array();
    return $this;

如果你想链接你的表单验证方法,返回 $this 很重要。

【讨论】:

【参考方案7】:

在较新的 3.X 版本中,清除 MY_Form_validation.php 库中的 set_value 、 $_POST=array()$this-&gt;_field_data = array();。试试

Clear form data after success codeigniter using php not jquery

【讨论】:

【参考方案8】:

d5avard 的答案是错误的,CI 表单验证应该将规则数组解析为它:如果您不这样做,您可以对发布的数据使用表单验证,但不能使用覆盖数据。

将此文件另存为 Libraries/MY_Form_validation.php

    /**
     * Class MY_Form_validation
     * @description extension of the CI_Form_validation
     * @property CI_DB_query_builder db database driver
     * @property CI_Benchmark benchmark
     * @property CI_Input input
     * @property CI_Output output
     */
    class MY_Form_validation extends CI_Form_validation
    
        /**
         * MY_Form_validation constructor.
         * @param array $rules
         */
        function __construct($rules = array())
        
            parent::__construct($rules);
            $this->_error_prefix        = '<div class=""><p>';
            $this->_error_suffix        = '</p></div>';
        

        /**
         * Resets the form validation class for multiple runs.
         * @param array $rules
         */
        public function initialise($rules = array())
        
            if (count($rules) == 0 )
            
                require (APPPATH.'config'.DIRECTORY_SEPARATOR.'form_validation.php');
                $this->_config_rules = $config;
            
            else
            
                $this->_config_rules = $rules;
            
            $this->_field_data          = array();
            $this->_error_array         = array();
            $this->_error_messages      = array();
            $this->_error_prefix        = '<div class=""><p>';
            $this->_error_suffix        = '</p></div>';
            $this->error_string         = '';
        
    

【讨论】:

以上是关于Codeigniter 表单验证 - 成功后如何取消设置表单值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在codeigniter中验证表单

Codeigniter:如何构建使用表单验证和重新填充的编辑表单?

如何使用 CodeIgniter 的表单验证类验证“不匹配”类型?

在 Codeigniter 中,如何将第三个参数传递给回调(表单验证)?

使用 Get 参数时如何验证 Codeigniter 中的表单字段?

如何在 CodeIgniter 中为 is_unique 表单验证启用查询生成器?