一.服务器配置
开发环境:
Win7
apache2.4.4
Zendframework 1.11.1
PHP5.4.12
MySQL 5.2.12
需要配置Apache的http.conf文件,开启URL的rewrite功能:
LoadModule rewrite_module modules/mod_rewrite.so
二.建立项目
在网站根目录下建立目录关系:
/mytest
/application
/controllers
/models
/views
/filters
/helpers
/scripts
/library
/public
/images
/scripts
/styles
Zend Framework 的控制器 Zend_Controller 被设计支持使用clean urls 的网站。为实现这个目的,所有的请求需要通过单一的index.php 文件,这就是所知的启动文件(bootstrapper)。这给我们提供了程序中所有页面的中心点并确保运行环境配置正确。我们用.htaccess文件来实现这个目的,.htaccess 在mytest 的根目录中,内容如下:
文件:mytest/.htaccess
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
RewriteRule 非常简单并可以翻译为“对任何url, 重定向到index.php”。
然而,对于图像,JavaScript 和CSS 文件的请求不应该重定向到启动文件,把这些文件放到public 目录下mytest/public 下:
文件:mytest/public/.htaccess
RewriteEngine off
虽然我们当前的rewrite rules不需要太严格,但我们还是在application 和library 目录下添加一些.htaccess 文件用来保护我们的程序:
文件:mytest/application/.htaccess
deny from all
文件:mytest/library/.htaccess
deny from all
三.网站
1.启动文件
接下来我们开始正式开始这个项目,首先是启动文件,也就是放在mytest根目录下的index.php它是个跳转的文件,在里面告诉请求执行那些操作
文件mytest/index.php
<?php
error_reporting ( E_ALL | E_STRICT ); //开启错误报告
date_default_timezone_set( 'Asia/Shanghai' ); //配置地区
set_include_path ( '.' . PATH_SEPARATOR. './library' . PATH_SEPARATOR . './application/models/' . PATH_SEPARATOR . get_include_path () ); //配置环境目录
include "Zend/Loader.php"; //载入zend框架
Zend_Loader::loadClass ( 'Zend_Controller_Front' );
Zend_Loader::loadClass ( 'Zend_Config_Ini' );
Zend_Loader::loadClass ( 'Zend_Registry' );
Zend_Loader::loadClass ( 'Zend_Db' );
Zend_Loader::loadClass ( 'Zend_Db_Table' );
Zend_Loader::loadClass ( 'Zend_Auth' );
Zend_Loader::loadClass ( 'Zend_Auth_Adapter_DbTable' );
$config = new Zend_Config_Ini('./application/config.ini','general' );
$registry = Zend_Registry::getInstance();//获得静态实例
$registry->set( 'config',$config );
$db = Zend_Db::factory( $config->db->adapter,$config->db->config->toArray());
Zend_Db_Table::setDefaultAdapter ( $db );
$frontController =Zend_Controller_Front::getInstance(); //获得控制器静态实例
$frontController->throwExceptions( true);
$frontController->setBaseUrl( '/mytest'); //我的项目路径
$frontController->setParam('useDefaultControllerAlways',true);
$frontController->setControllerDirectory('./application/controllers' );
// run!
$frontController->dispatch();
注意我们没有在文件的结尾放?>,因为它不是必须的并且有个好处是:我们可以防止当多余的whitespace 发生在?>后面出现难以调试的错误。
2.创建模型(M)
在mysql里建立数据表user,里面含有三个字段id,username,password:
CREATE TABLE `user`(
`id` int(4) unsignedNOT NULL AUTO_INCREMENTCOMMENT '用户id',
`username` varchar(50)DEFAULT NULL COMMENT '用户名',
`password` varchar(50)DEFAULT NULL COMMENT '密码',
PRIMARY KEY(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2DEFAULT CHARSET=latin1;
INSERT INTO `user`VALUES ('1','test1','test1');
然后我们在models里面建立自己的模型:
/mytest/application/models/user.php
<?php
class User extends Zend_Db_Table{
protected $_id;
protected $_username;
protected $_password;
public function checkUnique($username){
//注册验证用户是否存在
$select =$this->_db->select()->from('user')->where('username = ?',$username );
$result =$this->getAdapter()->fetchOne($select );
if ($result){
return true;
} else{
return false;
}
}
}
连接数据库的配置文件,Zend Framework 提供了一个Zend_Config 来提供灵活的面向对象访问配置文件。配置文件可以是一个PHP 数组,一个INI 文件或者XML 文件。我们这里使用INI 文件:
/mytest/application/config.ini
[general]
db.adapter = PDO_MYSQL
db.config.host = localhost
db.config.username = root
db.config.password =
db.config.dbname = test
3.创建视图文件(V)
如果使用Zend studio创建视图文件,可以在Zend studio里面右键项目—newàotherà会弹出下面页面,建立视图文件。
这里我们手动建立下,基于MVC模式写的Zendframework的视图文件扩展名是.phtml,新建如下文本文件:
文件:mytest/application/views/scripts/index/index.phtml
<?php echo$this->render('header.phtml');?>
<h1><?php echo $this->escape($this->title);?></h1>
<form name = "form1" action="index/login"method="post">
用户名:<input type="text" id="username" name="username"/><br/>
密码: <input type="password" id="password" name="password"/><br/>
<?php echo$this->username;?>
<input type="submit" name="submit" value="登陆">
</form>
<a href="/register/index">还没有账号,点此注册</a>
<div style="display:none;">
<table>
测试用户名和密码,用于查看数据库是否连接成功
<?php foreach($this->useras $u): ?>
<tr>
<td><?phpecho $this->escape($u->username);?></td>
<td><?phpecho $this->escape($u->password);?></td>
<td></td>
</tr>
<?php endforeach;?>
</table>
</div>
<?php echo$this->render('footer.phtml');?>
其中考虑到代码的公共部分可以重复使用,在视图里加了头部和脚部的文件。
文件:mytest/application/views/scripts/header.phtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xml:lang="en"lang="en">
<head>
<meta http-equiv="Content-Type"content="text/html;charset=utf-8"/>
Page9 of 18
<title><?phpecho $this->escape($this->title);?></title>
</head>
<body>
<div id="content">
文件:mytest/application/views/scripts/footer.phtml
</div>
</body>
</html>
注意,header.phtml和footer.phtml是放在index.phtml的上层目录上的,和index目录平行。
4.设置控制器(C)
在Zend studio里面右键项目—newàotherà会弹出下面页面,建立控制器。
假如我们把这个网站的首页设为登录界面,则在设置的默认控制器为
文件:mytest/application/controllers/IndexController.php
<?php
require_once 'Zend/Controller/Action.php';
class IndexController extends Zend_Controller_Action {
function init() {
$this->initView();
$this->view->baseUrl = $this->_request->getBaseUrl ();
Zend_Loader::loadClass( 'User' );
}
public function indexAction() {
$this->view->title ="欢迎登录";
$this->render();
}
function loginAction() {
// 登录
if ($this->getRequest ()->isPost ()) {
$username= $this->_request->get ("username" );
$password= $this->_request->get ("password" );
$pwd = 'w' . $password;
$pwd = md5 ( $pwd );
$user= new User ();
$auth= Zend_Auth::getInstance ();
$authAdapter= new Zend_Auth_Adapter_DbTable ($user->getAdapter (),'user'); // 匹配用户表
$authAdapter->setIdentityColumn( 'username')->setCredentialColumn ( 'password' ); // 选择数据库中哪两列用户名和密码来做认证
$authAdapter->setIdentity( $username )->setCredential ( $pwd ); // 前端表单传递过来的用户名和密码
$result= $auth->authenticate ( $authAdapter );
if ($result->isValid ()) {
$storage= new Zend_Auth_Storage_Session ();
$storage->write( $authAdapter->getResultRowObject () );
$this->_redirect( '/index/success');
}else {
$this->_redirect( '/index/error' );
}
}
}
function logoutAction() {
// 处理注销
$storage= new Zend_Auth_Storage_Session ();
$storage->clear();
$this->_redirect( '/index/index' );
}
function successAction() {
// 注册成功
}
function errorAction() {
// 注册failed
}
}
好了,现在在浏览器里输入你的URL就可以看到如下界面了,如果想要测试数据库连接可以把上面代码中的<div style="display:none;">的style去掉。
http://127.0.0.1/mytest
接下来我们来处理登录表单发送的POST请求,在action里面写了它的controller和action的名字在上面的代码中我们已经给出了,这里只做简单的说明:后台Indexaction通过接收前台发送的username和password尽心加密处理,为了增加安全级别,我们在密码前面加了一个字符再用md5()函数进行加密,然后通过框架中自带的类Zend_Auth_Adapter_DbTable中的方法进行密码比较。然后是逻辑判断之后我们会增加登录成功的页面和出错的页面:
文件:mytest\application\views\scripts\index\success.phtml
<?php
echo "login success!";
?>
文件:mytest\application\views\scripts\index\error.phtml
<?php
echo "user name or password error!";
以及一些CSS的文件:
文件:mytest /public/styles/site.css
body,html {
font-size:100%;
margin: 0;
font-family: Verdana,Arial,Helvetica,sans-serif;
color: #000;
background-color: #fff;
}
h1 {
font-size:1.4em;
color: #800000;
background-color: transparent;
}
#content {
width: 770px;
margin: 0auto;
}
label {
width: 100px;
display: block;
float: left;
}
#formbutton {
margin-left: 100px;
}
a {
color: #800000;
}
有了登录的例子我们可以继续写注册了。其实原理都一样,只不过使用的SQL语句有差别而已,我们还是先建立控制器controller和视图view文件吧.
注册功能的视图文件:
文件:mytest\application\views\scripts\register\index.phtml
<?php echo $this->render('header.phtml'); ?>
<h1><?phpecho $this->escape($this->title);?></h1>
<form name = "form1" action="/register/index"method="post">
用户名:<inputtype="text"id="username" name="username"/><br/>
密码: <inputtype="password"id="password" name="password"/><br/>
<?php echo$this->username;?>
<input type="submit"name="submit"value="注册"/>
</form>
<a href="/index/index">已有账号,点此登录</a>
<?php echo $this->render('footer.phtml'); ?>
文件:mytest\application\views\scripts\register\success.phtml
<?php
echo "register success!";
?>
<a href="/index/index">
<h1>点此登录</h1>
</a>
注册功能的控制器文件:
文件:mytest/application/controllers/RegisterController.php
<?php
require_once 'Zend/Controller/Action.php';
class RegisterController extends Zend_Controller_Action {
function init() {
$this->initView();
$this->view->baseUrl = $this->_request->getBaseUrl ();
Zend_Loader::loadClass( 'User' );
}
public function indexAction() {
if ($this->getRequest ()->isPost ()) {
$username= $this->_request->get ("username" );
//echo $username;
$password= $this->_request->get ("password" );
$pwd= 'w' . $password;
$pwd= md5 ( $pwd );
echo $pwd;
$user= new User ();
$auth= Zend_Auth::getInstance ();
if ($user->checkUnique ( $username )) {
echo "用户名已经存在!";
}else {
$data= array ('username'=> $username, 'password' =>$pwd );
$user->insert( $data );
$this->_redirect( '/register/success');
}
}else {
$this->view->title ="欢迎注册";
$this->render();
}
}
function successAction() {
// 注册成功
}
}
在创建模型文件的时候可能会有checkUnique()函数有所困惑,现在可以明确了,在注册的控制器里用到的。当用户填写表单数据发送到后台之后检测用户名是否存在,不存在时候可以在数据表中插入一条数据,注意一定是以数组形式插入。
最后看一下这个网站的目录结构了:
mytest/
/application
/controllers
/models
/views
/filters
/helpers
/scripts
/library
/public
/.htacccess