任何一个MVC框架都有使用的套路,或者称为流程。熟悉这个套路是应用框架进行快速开发的前提。如果要使用一个没有使用过的框架开发,最好做一个增删改查程序来先摸透这个框架的套路。
以下是一个自定义框架的增删改查版本,这个范本做的数据处理稍微复杂,所以也比一般的增删改查要复杂。这里记录一下范文,用于未来备用。
——————————————————
框架首先进入view目录根据mod定位类,然后根据act调用视图方法,在这个方法中可以按照套路调用相对应的action,action再去调用相对
应的model。(这里的View实际就是控制器角色,不过命名为View,实际混淆了控制器和视图)。这里的Action和Model实际都是MVC中
的M,M属于业务逻辑,根据实践,M可以有多种实现方式,TableGateway的方式是最常见的,这里的Action就是业务逻辑,Model就是
TableGateway,Action需要和数据库交互时,需要调用TableGateway进行操作,这个方式一般要求数据表和
TableGateway有一个对应关系,TableGateway只专注于和数据库的交互逻辑(也包含和第三方API交互)。具体来说,比如更新 和
插入操作,控制器接收数据,可以做一定的基本处理,提交给Action,Action做逻辑处理,调用Model更新或插入数据,然后返回结果给控制器,
控制器根据结果和视图交互。理论上,数据提交到Action是应该由控制器来负责的,但是实际上为了方便,往往在Action中直接接收来自客户端的数据
(比如$_GET
$_POST),这个行为实际上严重破坏了Action层,使得Action很难或者根本无法重用,如果这样操作,还不如直接在控制器中实现,根本不需要
绕个圈。
Action和Model都是MVC中的M,所以在控制器中使用Action和Model都是合理的。因为有些数据的获取,不一定非要经过 Action,只有需要对数据进行加工处理时(业务逻辑)才需要经过Action,Model虽然应该专注于和数据库的交互逻辑,但是也可以加入一些其它 的基本逻辑,特别是很简单的数据,根本不需要绕个圈经过Action来实现。由此可见,代码组织可能会引入混乱。业务逻辑可以写在控制器中,也写在 Action中,也写在Model中,看来,开发规范的问题是需要强制性要求才可以……
每个View类从BaseView继承:
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<?php
class TitleView extends BaseView{
public function __construct(){
parent::__construct();
}
public function view_modify(){
$checked = (! empty ( $_POST [ 'psites' ]) && is_array ( $_POST [ 'psites' ]))? $_POST [ 'psites' ]: array ();
// 接收数据
$title = array (
'title' =>! empty ( $_POST [ 'search' ])? $_POST [ 'search' ]: '' ,
'sites' => $checked ,
'erpCates' =>! empty ( $_POST [ 'erpCates' ])? $_POST [ 'erpCates' ]: ''
);
$freshMessage = '' ;
if (! empty ( $_REQUEST [ 'id' ])){
$id = $_REQUEST [ 'id' ];
// 判断$id是否存在
} else {
$freshMessage = '数据有误.' ;
}
// 调用Action
if (isset( $_POST [ 'type' ]) && ( $_POST [ 'type' ] == 'modify' )){
$modifyData = $title ;
$modifyData [ 'id' ] = $id ;
$modifyData [ 'type' ] = 'modify' ;
$success = A( 'title' )->act_addAndModify( $modifyData );
if ( $success ){
$_SESSION [ "freshMessage" ] = "标题成功编辑。" ;
header( "Location:index.php?mod=title&act=list" );
exit ;
} else {
$freshMessage = "编辑失败。" ;
}
}
$this ->smarty->assign( "freshMessage" , $freshMessage );
// 数据回显
$tree = A( 'erpCates' )->getSimpleCates();
$this ->smarty->assign( 'tree' , $tree );
// 更新失败时数据回显 依据提交的数据处理
if (isset( $_POST [ 'type' ]) && ( $_POST [ 'type' ] == 'modify' )){
$title [ 'id' ] = $id ;
$title = A( 'title' )->act_reproduce( $title );
} else {
$title = A( 'title' )->act_reproduceFromModify( $id );
}
$this ->smarty->assign( $title );
$this ->smarty->display( 'title_modify.html' );
}
public function view_add(){
$checked = (! empty ( $_POST [ 'psites' ]) && is_array ( $_POST [ 'psites' ]))? $_POST [ 'psites' ]: array ();
// 接收数据
$title = array (
'title' =>! empty ( $_POST [ 'search' ])? $_POST [ 'search' ]: '' ,
'sites' => $checked ,
'erpCates' =>! empty ( $_POST [ 'erpCates' ])? $_POST [ 'erpCates' ]: ''
);
$freshMessage = '' ;
if (isset( $_POST [ 'type' ]) && ( $_POST [ 'type' ] == 'add' )){
$addData = $title ;
$addData [ 'type' ] = 'add' ;
$success = A( 'title' )->act_addAndModify( $addData );
if ( $success ){
$_SESSION [ "freshMessage" ] = "标题成功添加。" ;
header( "Location:index.php?mod=title&act=list" );
exit ;
} else {
$freshMessage = "添加失败。" ;
}
}
$this ->smarty->assign( "freshMessage" , $freshMessage );
// 回显数据
$tree = A( 'erpCates' )->getSimpleCates();
$this ->smarty->assign( 'tree' , $tree );
$title = A( 'title' )->act_reproduce( $title );
$this ->smarty->assign( 'search' , $title [ 'title' ]);
$this ->smarty->assign( 'platformSite' , $title [ 'sites' ]);
$this ->smarty->assign( 'erpCates' , $title [ 'erpCates' ]);
$this ->smarty->display( 'title_add.html' );
}
// 列表
public function view_list(){
if (! empty ( $_SESSION [ "freshMessage" ])){
$this ->smarty->assign( 'freshMessage' , $_SESSION [ "freshMessage" ]);
unset( $_SESSION [ "freshMessage" ]);
}
$selectedCates = isset( $_REQUEST [ 'selectedCates' ])?trim( $_REQUEST [ 'selectedCates' ]): '' ;
$cates = A( 'title' )->act_searchCates( $selectedCates );
$this ->smarty->assign( 'cateList' , $cates [ 'searchCates' ]);
$this ->smarty->assign( 'erpCates' , $cates [ 'erpCates' ]);
$selectedSite = isset( $_REQUEST [ 'sites' ])? $_REQUEST [ 'sites' ]: '' ;
$sites = A( 'title' )->act_searchSites( $selectedSite );
$this ->smarty->assign( 'platformSiteView' , $sites );
// 列表数据
$this ->view_listShow();
$this ->smarty->display( 'title_list.html' );
}
// Ajax删除
public function view_delete(){
$this ->view_delData();
}
}
|
对于一个列表,可以调用view_listShow(),内部会去调用对应的action的act_getDataList获取数据(一 页),act_getDataCount获取总数量传递给一个分页类,最终注册到list和show_page变量(Smarty)。一个基本套路,对于 更新和插入,都是先接收数据,然后判断是否应用更新插入,然后是处理回显数据。先接收的数据可以应用到插入和更新中去,也方便后面的数据回显,避免了多次 组装数据,另外也方便抽象业务逻辑(不需要传递$_GET和$_POST这类变量)。由于提交的数据只是用户选中的数据,所以要根据选中的数据,经过处理 后传递回到视图(比如一个下拉框,选中了某一个项,但是回显时需要把整个下拉框数据都带上,而且标记选中的项),更新和插入基本类似,插入回显的数据是根 据客户提交的数据,而更新回显的数据有两个,第一次回显是保存在数据库中的数据,第二次回显是是客户端提交的数据。
注意:如果使用封装的方法,就必须在对应的Action中定义对应的方法(默认是不存在的):
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
【责任编辑:】(Top) 返回页面顶端
下一篇:TFS PHP客户端栏目导航Navigation贴心
全国7×24小时客服热线
安全
病毒杀除率高于99%
稳定
网站可用性高于99.9%
实力
服务68家上市企业及集团公司
亿恩科技手机站
关注亿恩科技微信
|