PHP面向对象编程:处理表单提交的最佳策略是什么?

3
我们已经建立了自定义表单,目前这些表单已经非常完善并且经过了深思熟虑的设计。每个类都有其自己的职责,迄今为止,基本的面向对象编程原则已经被使用,例如继承、多态性、封装等等。表单的每个元素都是一个对象,所有对象都被收集并在运行时启动。
现在我们已经到达了表单处理的部分,我们对如何处理这一部分感到困惑,并希望询问是否有任何指导意见?
例如,是否有替代方案,比如创建一个类来负责检查表单是否已经提交并提供方法来收集post数据、验证等等,或者人们仍然像以前那样使用快速条件来检查表单是否已提交?
if(isset($_POST["var"])
{
//process form
} else {
//show form
}

最好使用单独的操作页面进行处理吗?

基本上,我不想编写一些无法重用或利用面向对象编程概念的可怕代码。我们希望在不使用任何框架的情况下实现某些内容。


面向对象编程(OOP)与你在这里尝试实现的目标有什么关系? - Gal
yes123部分正确,我认为你需要做的是使用MVC所使用的模式。一次又一次地,人们认为Yii或Zend是MVC。它不是,它是一个使用MVC模式并添加了大量额外功能的框架。(好吧,这是不同的争论)。然而,我认为如果你深入研究模式,它会有所帮助。然后你就可以实现你需要的代码。如果勇敢的话,可以尝试《设计模式》(Gang of Four)书籍,或者获取一本关于PHP GOF模式的书籍,或者查看提供示例的网站。面向对象编程是编写代码的一种方式,而不是构建网站的方式。另外,也要看看框架如何处理它,阅读代码! - PurplePilot
谢谢PurplePilot,比yes123的评论更有建设性... - Steve Took
完全没有理解“sombe”的重点。已经实现的与面向对象编程(OOP)有很大关系,问题是如何在我们现在尝试实现的内容中跟随这条路线。如果没有好话要说,为什么要评论呢? - Steve Took
@Steve - 这个问题似乎是面向过于通用和广泛的,无法涵盖。如果出于某种原因,框架不适合您,那么您可以借鉴它们。生成和处理表单是大多数这些框架的核心。 - Anurag
谢谢Anurag,我认为大多数评论者实际上读入了太多问题。只是好奇人们对于在没有框架的情况下使用OOP进行表单处理的想法或方法。我们不是在寻找最佳解决方案或重新发明轮子,而是将其作为我们已经完成的工作的一部分来实现,主要是为了开发我们自己的开发实践。 - Steve Took
2个回答

1
我会尝试使用这样的结构:

// public function __construct( ValidatorInterface $validator )
$form = new Form( new Validator );


// public function add_field( $name , array $rules = array() )
$form->add_field( 
   'name',  
    // that would be $_POST['name'] , and in template file <?php echo $name ?>
    array(
       'required'  => 'Full Name is required' 
       // for validator to execute is_required()
    ));
$form->add_field( 
   'email' ,
    array( 
       'required'  => 'Email Address is required', 
       'email'     => 'A valid email address is required' 
       // for validator to execute is_email()
    ));
$form->add_field( 'country' );

//name of submit button
$for->add_submitter( 'submit' );
// etc 

$page = new Template();
$page->use_file( 'contact.php' );

if( $form->is_submitted() )
{
   // gathers all the $_POST's from registered fields
   $form->collect();

   if ($form->is_valid() )
   {
      $page->use_file( 'done.html' );
      // do some stuff 
   }
   else
   {            
      // public function populate( TemplateInterface $template )
      // assigns field values and error messages to the template
      $form->populate( $page );         
   }

}

echo $page->render();   

基于这段代码的Template类:http://codeangel.org/articles/simple-php-template-engine.html


更新

实现注册新字段的方法

public function add_field( $name , array $rules = array() )
{       
   if ( !array_key_exists( $name , $this->_fields ))
   {
      $this->_fields[ $name ] = array();
   }

   $this->_fields[ $name ]['rules'] = $rules; 
}

查找所有已注册字段值的方法实现

public function collect()
{           
   $field_names = array_keys( $this->_fields );

   foreach ( $field_names as $name )
   {                
      $this->_fields[ $name ]['value'] = $this->_collect_value( $name );                
   }

}

protected function _collect_value($name)
{

   $value = null;

   if ( isset( $_POST[ $name ] ) )
   {
      $value = $_POST[$name];       
   }

   $value = trim( $value );

   if ( empty( $value ) ){
      $value = null;    
   }

   return $value;

}   

数据收集是一个非常简单的过程。

在调用 is_valid() 方法时,从本地变量获取验证器实例,并对每个注册的表单字段执行操作(通常使用有用的 PHP filter_var() 函数)。


谢谢Teresko,虽然不完全是我想要的,但很接近。我在寻找人们对表单处理部分的想法,例如:// gathers all the $_POST's from registered fields $form->collect(); 这种方法是否只是获取和排序全局变量,如$_POST和$_GET,并且大多数人或框架都是这样做的? - Steve Took
@Steve Took,我不确定你所说的“processing”是什么意思,因为Form元素的验证并不是表单本身的责任。这就是为什么它应该在构造函数中提供外部Validator。表单只需要收集所有数据。 - tereško
使用您的术语“数据收集”是我想表达的意思;-)这些方法收集数据的方式非常适合我们迄今为止所取得的成果。我们已经有了注册表单元素和验证的方法,因此这个概念将非常有效,非常感谢。您真是一个传奇! - Steve Took

1
你们都忽略了一个非常重要的概念。你不想展示表单,而是要求用户输入一些内容。实际上,你需要像这样的东西:
$rules = array(
  "name" => array("not_empty"),
  "email" => array("not_empty", "email")
);
$callback = array($this, "handle_valid_post_data");
$ui->request_input($rules, $callback);

遗憾的是,没有框架可以做到这一点,所以你必须自己实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接