在php中使用类似django的form类

用php有两个月了,说实话用惯了django,再用php开发真的有点郁闷,简单列一下,并非批评,仅为入门的同学少走弯路:

  1. 取不到post的数据
    当url为如下形式:

    1
    
    xx.com/?mod=x&act=y

    而method又为post的时候,post的数据会取不到;必须改成如下形式:

    1
    
    xx.com?mod=x&act=y
  2. 字符串连接
    这么写代码是会报错滴:

    1
    
    echo 1."xx";

    必须这么写才行:

    1
    
    echo 1 ."xx";
  3. require之后,不知道自己引入了些什么
    这个地方,如果和C或者C++来比确实也没啥问题,关键是python的from x import y 的方式实在是让人赏心悦目,所以忍不住抱怨下。

OK,抱怨完了,言归正传。
其实这些问题都还好,仔细点都能解决,最让我不爽的是php的所有框架(不排除我孤陋寡闻,欢迎大家指教)居然都没有提供一个类似于django的form类。
心灰意冷之时,突然想起来之前看到过一个仿django的php框架,虽然整个框架还有很多问题,不过form类这部分应该完成了吧。
pluf:http://www.pluf.org/
果然不出所料!
看过我之前博文的朋友应该都知道我把CodeIgniter的db访问类单独拆了出来(参见:抽离CodeIgniter的数据库访问类!),没错,这次我又做了同样的事情。
拆分的方法这里就不详细描述了,其实就是SafeString.php这个文件从别的目录拷贝过来,并且定义了一个pluf_form_inc.php来require所有文件。我们看一下独立之后的文件目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|~Form/
| |~Field/
| | |-Boolean.php
| | |-Date.php
| | |-Datetime.php
| | |-Email.php
| | |-File.php
| | |-Float.php
| | |-Integer.php
| | |-ReCaptcha.php
| | |-Slug.php
| | |-Url.php
| | `-Varchar.php
| |~Widget/
| | |~SelectMultipleInput/
| | | `-Checkbox.php
| | |-CheckboxInput.php
| | |-DatetimeInput.php
| | |-FileInput.php
| | |-HiddenInput.php
| | |-Input.php
| | |-PasswordInput.php
| | |-ReCaptcha.php
| | |-SelectInput.php
| | |-SelectMultipleInput.php
| | |-TextareaInput.php
| | |-TextInput.php
| | `-TinyMCEInput.php
| |-BoundField.php
| |-Field.php
| |-FieldProxy.php
| |-Invalid.php
| |-Model.php
| `-Widget.php
|-Form.php
|-pluf_form_inc.php
|-SafeString.php
`-test.php

OK,接着我们来写一个简单的测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
require_once 'pluf_form_inc.php';
 
class MyApp_Form_Simple extends Pluf_Form
{
    public function initFields($extra=array())
    {
        $this->fields['name'] = new Pluf_Form_Field_Varchar(
            array('required' => true,
            'label' => __('List name'),
            'initial' => 'Here the name',
            'help_text' => __('For example: "Happy stuff".'),
        ));
 
        $this->fields['description'] = new Pluf_Form_Field_Varchar(
            array('required' => false,
            'label' => __('Description'),
            'widget' => 'Pluf_Form_Widget_TextareaInput',
            'widget_attrs' => array('rows' => 5,
            'cols' => 75),
        ));
 
        $this->fields['list'] = new Pluf_Form_Field_Varchar(
            array('required' => true,
            'label' => __('list'),
            'initial' => 1,
            'widget' => 'Pluf_Form_Widget_SelectInput',
            'widget_attrs' => array(
                'choices' => array(
                    array(
                        '所有'=>0,
                        '部分'=>1,
                    )
                ),
            )
        ));
    }
}
$form = new MyApp_Form_Simple(
    array(
        'name'=>'dantezhu',
        'list'=>1
    )
);
 
echo $form->render_p();
echo "\n";
 
echo var_export($form->isValid());
echo "\n";
 
echo $form->field('name')->labelTag();
echo "\n";
echo $form->field('name');
echo "\n";
 
echo var_export($form->clean(),true);

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<p><label for="id_name">List name:</label> <input name="name" type="text" id="id_name" value="dantezhu" /> For example: "Happy stuff".</p>
<p><label for="id_description">Description:</label> <textarea cols="75" rows="5" name="description" id="id_description"></textarea></p>
<p><label for="id_list">list:</label> <select name="list" id="id_list">
<optgroup label="0">
<option value="0">所有</option>
<option value="1" selected="selected">部分</option>
</optgroup>
</select></p>
true
<label for="id_name">List name</label>
<input name="name" type="text" id="id_name" value="dantezhu" />
array (
  'name' => 'dantezhu',
  'description' => '',
  'list' => 1,
)

完全实现了django的form类一样的功能!
当然,相信大家也看到了,由于语言上的欠缺,php写出来的form定义要比python繁琐很多,但是总算是实现了,不错!
代码还是同往常一下,放在svn上提供下载:
http://code.google.com/p/vimercode/source/browse/#svn%2Ftrunk%2Fpluf_form

PS:
最近做了一套小型的支付系统,近期也会和大家分享一下





原创文章,版权所有。转载请注明:转载自Vimer的程序世界 [ http://www.vimer.cn ]

本文链接地址: http://www.vimer.cn/?p=2187

12 个评论 在 “在php中使用类似django的form类”

  1. Eric 说:

    验证规则跟视图表现混在一起好像不太好吧?如果某个form要复用怎么办。而且貌似也没法做到对html的深度控制。

    [回复]

    Dante 回复:

    呃,对html深度控制这里是可以做到的,要配合模板来一起用~
    验证规则和视图混在一起,这一点怎么说呢,换个角度,这个form就是http的表单与php之间的适配层,这样考虑就会觉得合理很多。

    这样设计的好处可以看一下django的文档,节省了很多冗余代码。

    [回复]

  2. francis 说:

    就django的form类真的不如一些已有PHP框架的ActiveForm类好用;

    还有字符串输出,通常用 echo 1, ‘hello world’;

    [回复]

    Dante 回复:

    呃,用php时间不长,很多php的惯用用法还不熟。

    可能我孤陋寡闻了,不过django的form口碑还是不错的,你说的ActiveForm在google上貌似搜不到,方便给个链接地址?

    [回复]

    francis 回复:

    表单的,比如 http://blog.csdn.net/yjj1s/archive/2010/07/18/5744279.aspx 这里。

    [回复]

  3. seatle 说:

    就没有一个框架会缺少这个功能,只是你不知道而已

    [回复]

    Dante 回复:

    请指教。

    [回复]

  4. Jam 说:

    PHP的框架我推荐Yii Framework,模块化组件化做的不错。http://www.yiiframework.com/

    不过我很讨厌在Python中使用Django Form或在PHP中使用像Yii 中的ZiiWidgets之类的东西(不得不说Yii的ZiiWidgets做得很强大)(另外Yii的WebForm功能也很强大)。
    我更喜欢亲手写HTML和JS代码,可控性更高,或许是因为自己更了解如何模块化前端HTML、JS代码的缘故,这些生成HTML的东西一看就不喜欢

    [回复]

    Dante 回复:

    据说yii确实不错,不过php用的少。。

    关于Form这里,其实我也是反对在大型项目里面用这种自动生成html,或者自动生成sql建表语句的组件的。
    不过Form这里,我主要是用他来做参数检查,要比自己去写一堆if else然后输出错误要简洁有效的多。

    [回复]

  5. 7hao 说:

    其实基本上PHP框架里都有FORM类,比如CI的脚手架功能,都很贴心

    实在不行,自己实现一个

    这就是PHP的乐趣所在吧

    [回复]

我要评论

*

*