Note on <Zend Framework - A Beginner's Guide> - 03

106 篇文章 0 订阅
9 篇文章 0 订阅

Chapter 3: Working with Forms


咕~~(╯﹏╰)b,没想到还是有些人来看。


基本输入

这一章的内容比较简单,在ZF框架里,form标签和表单元素的标签都被封装成类,通过这些类可以简化输出构成表单的HTML内容,这些类具有一些方法用来设定表单或者输入控件的属性,我只举一个书中例子:

<?php
	class Form_Example extends Zend_Form
	{
		public function init()
		{
			// initialize form
			$this->setAction('/sandbox/example/form')
				->setMethod('post');
			
			// create text input for name
			$name = new Zend_Form_Element_Text('name');
			$name->setLabel('Name:')
				->setOptions(array('id' => 'fname'));
			
			// create radio buttons for type
			$type = new Zend_Form_Element_Radio('type');
			$type->setLabel('Membership type:')
				->setMultiOptions(
					array(
						'silver' => 'Silver',
						'gold' => 'Gold',
						'platinum' => 'Platinum'
					)
				)
				->setOptions(array('id' => 'mtype'));
			
			// create checkbox for newsletter subscription
			$subscribe = new Zend_Form_Element_Checkbox('subscribe');
			$subscribe->setLabel('Subscribe to newsletter')
						->setCheckedValue('yes')
						->setUncheckedValue('no');
			
			// attach elements to form
			$this->addElement($name)
				->addElement($type)
				->addElement($subscribe);
		}
	}


这个示例中,先创建一个form元素,再创建三个输入控件,然后将三个控件加入form中。ZF封装的HTML表单元素有16个:

Element ClassDescription
Zend_Form_Element_Text 
Zend_Form_Element_Hidden 
Zend_Form_Element_Password 
Zend_Form_Element_Radio 
Zend_Form_Element_Checkbox 
Zend_Form_Element_MultiCheckbox 
Zend_Form_Element_Select 
Zend_Form_Element_MultiSelect 
Zend_Form_Element_Textarea 
Zend_Form_Element_File 
Zend_Form_Element_Image 
Zend_Form_Element_Button 
Zend_Form_Element_Hash 
Zend_Form_Element_Captcha 
Zend_Form_Element_Reset 
Zend_Form_Element_Submit 

注意,除了通常在HTML4里会见到的表单控件外,ZF有两个特别的类型:Hash和Captcha。此处难免会有新的疑虑,即是HTML5里新加的元素将会怎样?


验证与过滤

除了上面提到的之外,ZF最重要的,是提供一个机制,可以方便地给这些表单控件接收到的用户数据增加验证和过滤。比如,要给一个文字输入增加一个过滤器,将其中的特殊符号进行HTML编码,你可以这样做:

// filter special characters
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Username:')
	->setOptions(array('size' => '16'))
	->addFilter('HtmlEntities');


也有另外一个做法:

// filter special characters
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Username:')
	->setOptions(array('size' => '16'))
	->addFilter(new Zend_Filter_HtmlEntities());


ZF提供的过滤器有:



验证器的做法与过滤器类似:

// should contain only integer values between 1 and 100
$age = new Zend_Form_Element_Text('age');
$age->setLabel('Age:')
	->setOptions(array('size' => '4'))
	->setRequired(true)
	->addValidator('Int')
	->addValidator('Between', false, array(1,100));


当然,这些代码按逻辑上说应该是放在接收数据提交的PHP代码块里,可是从书中的示例来看,它们的调用却是在生成form的时候,所以究竟ZF实现这些验证的具体做法是如何,现在还不清楚,一种可能是:它们动态生成Ajax代码来在客户端执行这些验证操作,就像.NET里那样,但是书中在抛砖引玉时拿出的传统代码却又不是Ajax代码,而是在接收表单数据的PHP代码中的验证处理。总之,需要进一步看下文才知道。


ZF框架提供的验证器有:


从79页的Ask Expert部分可以推敲,这些验证和过滤是在server端用PHP来完成的,即是说是在处理提交的表单数据的时候。


在ZF中处理提交的表单数据时,可以将验证器和过滤器链在一起使用,像刚刚上面那段示例代码中,将两个验证器都应用到age的数据上,这两个验证会自动被逐个逐个执行。当然从后面的代码示例来看,将验证器和过滤器同时混合起来链在一起也没问题。另外,验证器有一个使用上的特点,即可以指定是否在某个验证失败时就即刻停止处理,返回错误,这个是通过addValidator()的第二个参数来指定的。


处理提交的数据


其实这里主要是三个方法,不如用书中例子来解释:

<?php
	class ExampleController extends Zend_Controller_Action
	{
		public function formAction()
		{
			$form = new Form_Example;
			$this->view->form = $form;
			// check the request
			// run the validators
			if ($this->getRequest()->isPost()) 
			{
				if ($form->isValid($this->getRequest()->getPost())) 
				{
					// valid data: get the filtered and valid values
					// do something, save to database or write to file
					// display a success view
					$values = $form->getValues();
					$this->_redirect('/form/success');
				} 
				else 
				{
					// invalid data: get the error message array
					// for manual processing (if needed)
					// redisplay the form with errors
					$this->view->messages = $form->getMessages();
				}
			}
		}
	}
?>


注意其中的三个form类的方法:isValid()、getValues()、getMessages()。


继续Square实例

下面到了实践的时候了,来回到贯穿书中的square项目。上次在给这个项目创建主布局时,在菜单里加了个contact条目,而它指向的内容一直是空白的,现在就来为这个项目创建一个联络表单。


为了完成这个实验,需要先找到书中使用的字体,用来在CAPTCHA输入中使用的。


先在/public/下面创建个fonts文件夹,把这个字体放进去。并且再创建一个captcha文件夹。然后创建这个文件:/library/Square/Form/Contact.php。其内容书中有。


现在提一些关于ZF框架的自动加载类的机制,在自定义的类的类名前加一个自定义的字符串,比如在这个示例中为“Square_”。然后在application.ini中注册这个字符串。ZF框架就会自动为你加载这个类的定义文件,简单说就是你不需要自己写include指令来加载你写的类定义PHP文件。而这个过程在ZF的术语中被称为“注册自定义命名空间”(register custom namespace),当然这个写在类名中并被注册的前缀就是namespace。

在刚刚创建的Contact.php中,我们自定义的类的名称为Square_Form_Contact,那么现在来注册这个命名空间:在application.ini中添加:

autoloaderNamespaces[] = "Square_"


还没完,还需要创建一个controller来使用这个form。这个过程包括创建controller文件和view文件并在ini文件中指定新的路径,和在master layout中修改contact的a标签等等。。。


另外,在我的case中,我需要修改CAPTCHA图片的路径为:

    // create captcha
    $captcha = new Zend_Form_Element_Captcha('captcha', array(
      'captcha' => array(
        'captcha' => 'Image',
        'wordLen' => 6,
        'timeout' => 300,
        'width'   => 300,
        'height'  => 100,
        'imgUrl'  => '/square/public/captcha',	// in my case
        'imgDir'  => APPLICATION_PATH . '/../public/captcha',
        'font'    => APPLICATION_PATH . '/../public/fonts/LiberationSansRegular.ttf',
        )
    ));


最后见到的页面为:

contact-form


同时,我也需要修改表单的提交链接,来适应我自己的情况,在自定义Form的类定义里:

$this->setAction('square/public/contact/index')



在完成这个实验的过程中,我见到这本书的附带代码里,application.ini中用#来标示为注脚,可是在我所使用的ZF版本中,这个做法会弹出错误,生成这个做法已经被废弃:

<b>Fatal error</b>:  Uncaught exception 'Zend_Config_Exception' with message 'Comments starting with '#' are deprecated in D:\idsweb\htdocs\square\application/configs/application.ini on line 16


error-with-comment


如果想要成功提交这个表单,需要安装Apache的服务器本身是有一个有效的STMP服务器,或者能够提供邮件功能服务的机器,否则即使将代码中$mail->addTo('info@square.example.com');的邮箱地址换成你自己的有效邮箱也不行。

mail-send-error

这个过程中Zend_Mail的send()方法抛出一个异常,而这个异常在ErrorController中被捕捉,于是它得到了控制,输出了上面的错误信息。


所以现在我们能够尝试的,只是在输入的数据不符合要求的情况下,ZF自带的验证器会产生怎样的效果:

fail-validation


注意:ZF的表单类的工作机制:如果验证失败的话,它会将用户填写的数据保留在表单里,同错误信息一同显示给用户。


这一章最后讨论的内容是,如何修改ZF框架输出的表单和表单元素的HTML内容,这个话题是针对网页设计者而言的,多数时候,比如错误信息,我们可能会有一个整体的设计,将表单提交后的提示信息统一显示在某个位置,并且按照指定的设计样式,所以用来包住提示信息的HTML标签以及它出现的位置是极为多变的,而为了提供这个能力,ZF框架有一套关于Decorators的类和与之相关的方法。这本书在这里给出的例子极为简单,只是将一个按钮包在一个p标签中:

<?php
class Form_Example extends Zend_Form
{
	...
	public $buttonDecorators = array(
		array('ViewHelper'),
		array('HtmlTag', array('tag' => 'p'))
	);

	public function init()
	{
		...
		
		// create submit button
		$submit = new Zend_Form_Element_Submit(
			'submit', 
			array('class' => 'submit')
		);
		
		$submit->setLabel('Sign Up')
		->setDecorators($this->buttonDecorators);
	}
}
...


这个地方更深入的地方我也一知半解,作者也不打算继续探讨。总之,一般来说,都是需要自己扩展Zend_Form_Decorator_Abstract类。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值