赵工的个人空间


专业技术部分转网页计算转业余爱好部分


 编程语言

常用的编程语言
C#编程语言基础
C#面向对象与多线程
C#数据及文件操作
JavaScript基础
JavaScript的数据类型和变量
JavaScript的运算符和表达式
JavaScript的基本流程控制
JavaScript的函数
JavaScript对象编程
JavaScript内置对象和方法
JavaScript的浏览器对象和方法
JavaScript访问HTML DOM对象
JavaScript事件驱动编程
JavaScript与CSS样式表
Ajax与PHP
ECMAScript6的新特性
Vue.js前端开发
PHP的常量与变量
PHP的数据类型与转换
PHP的运算符和优先规则
PHP程序的流程控制语句
PHP的数组操作及函数
PHP的字符串处理与函数
PHP自定义函数
PHP的常用系统函数
PHP的图像处理函数
PHP类编程
PHP的DataTime类
PHP处理XML和JSON
PHP的正则表达式
PHP文件和目录处理
PHP表单处理
PHP处理Cookie和Session
PHP文件上传和下载
PHP加密技术
PHP的Socket编程
PHP国际化编码
MySQL数据库基础
MySQL数据库函数
MySQL数据库账户管理
MySQL数据库基本操作
MySQL数据查询
MySQL存储过程和存储函数
MySQL事务处理和触发器
PHP操作MySQL数据库
数据库抽象层PDO
Smarty模板
ThinkPHP框架
Python语言基础
Python语言结构与控制
Python的函数和模块
Python的复合数据类型
Python面向对象编程
Python的文件操作
Python的异常处理
Python的绘图模块
Python的NumPy模块
Python的SciPy模块
Python的SymPy模块
Python的数据处理
Python操作数据库
Python网络编程
Python图像处理
Python机器学习
TensorFlow深度学习
Tensorflow常用函数
TensorFlow用于卷积网络
生成对抗网络GAN


首页 > 专业技术 > 编程语言 > ThinkPHP框架
ThinkPHP框架

ThinkPHP需要PHP5.0以上版本支持,支持MySQL、MsSQL、PgSQL、Sqlite、Oracle等数据库。ThinkPHP中,使用add()、save()、select()、delete()方法表示对数据库的创建Create、更新Update、读取Read、删除Delete操作,即CURD。

1.ThinkPHP目录结构:

ThinkPHP框架中的目录结构分为系统目录和项目目录两部分。其中系统目录是下载的ThinkPHP框架类库。一般使用ThinkPHP作为系统目录文件夹名。


目录

作用

Common

包含框架的一些公共文件、系统定义和惯例配置等

Lang

目录语言文件夹,支持的语言包有简体中文、繁体中文、英文

Lib

系统的基类库目录

Tpl

系统的模板目录

Mode

框架模式扩展目录

Vendor

第三方类库目录

项目目录是用户实际的目录。ThinkPHP采用自动创建文件夹机制,当用户设置好ThinkPHP核心类库后,编写运行入口文件,则相关应用到的项目目录就会自动生成。一般使用Home或App为项目目录文件夹名。


目录

主要作用

index.php

项目入口文件

Common

项目公共目录,放置项目公共函数

Lang

项目语言包目录(可选)

Conf

项目配置目录,放置配置文件

Lib

项目基目录,通常包括Action和Model目录

Tpl

项目模板目录

Runtime

项目运行时目录,包括Cache、Temp、Data和Log

有的项目还会使用后台管理项目目录Admin,多项目时往往使用Public公共目录放置CSS、js脚本及Images图片,分别建立css、images和js子目录。

2.自动生成项目目录:

ThinkPHP采用自动创建文件夹机制,需要按如下步骤操作:
·网站根目录下创建文件夹,可以命名为a
·将ThinkPHP核心类库存储于a目录下
·编写入口文件index.php,并存储在a目录下,代码为:
<?php
define('THINK_PATH','ThinkPHP'); //定义ThinkPHP框架路径,相对于入口文件
define('APP_NAME','a'); //定义项目名称
define('APP_PATH','.'); //定义项目路径
require(THINK_PATH."/ThinkPHP.php"); //加载框架入口文件
App::run(); //实例化一个网站应用实例
?>

3.命名规范:

ThinkPHP框架自身有一套规范。其中的命名规范为:
·类文件都以.class.php为后缀,使用驼峰法命名,并且首字母大写
·函数、配置文件等其他类库文件一般使用.php为后缀
·类名与文件名一致,大小写敏感
·函数的命名使用小写字母和下划线方式
·Action控制器类以Action为后缀,如UserAction、InfoAction
·模型名以Model为后缀,如UserModel、InfoModel
·方法的命名使用驼峰法,并且首字母小写
·属性的命名使用驼峰法,并且首字母小写
·以双下划线__开头的函数或方法作为魔法方法
·常量以大写字母和下划线命名
·语言变量以大写字母和下划线命名,以下划线开头的语言变量常用于系统语言变量
·数据表和字段采用小写加下划线方式命名
还有一种单字母大写函数,通常是某些操作的快捷定义,或者有特殊作用。
ThinkPHP默认使用UTF-8编码,要确保程序文件采用UTF-8编码格式保存,并且去掉BOM信息头。

4.ThinkPHP配置:

配置文件是ThinkPHP框架程序运行的基础条件,很多功能都需要在配置文件中设置之后才能生效,包括URL路由功能、页面伪静态和静态化等。
ThinkPHP框架中所有配置文件的定义格式均采用PHP数组方式:
<?php
return array(
   'APP_DEGUG'=>true,
   'URL_MODEL'=>2,
);
?>
配置参数不区分大小写,但习惯上保持大写定义原则。还可以使用二维数组来配置更多信息:
<?php
return array(
   'APP_DEGUG'=>true,
   'USER_CONFIG'=>array(
         'USER_AUTH'=>true,
         'USER_TYPE'=>2,
   ),
);
?>
项目配置文件默认存储于项目的conf目录。
调试配置文件debug.php位于项目配置目录common下面,可以进行一些开发模式所需要的配置。系统默认的调试配置文件中设置如下内容:开启日志记录、关闭模板缓存、记录SQL日志、关闭字段缓存、开启运行时间详细显示、开启页面Trace信息显示、严格检查文件大小写。

5.项目构建流程:

用户只需要定义好项目的入口文件,在第一次访问入口文件时,系统会自动根据在入口文件中所定义的目录路径,迅速创建好项目的相关目录结构。然后就可以进行一些工作:
1)创建数据库:
将创建数据库的指令写入conf目录下的config.php:
<?php
return array(
   'APP_DEGUG'=>true, //开启调试模式
   'DB_TYPE'=>'mysql', //数据库类型
   'DB_HOST'=>'localhost', //数据库服务器地址
   'DB_NAME'=>'demo', //数据库名称
   'DB_USER'=>'root', //数据库用户名
   'DB_PWD'=>'111', //数据库密码
   'DB_PORT'=>'3306', //数据库端口
   'DB_PREFIX'=>'think_', //数据表前缀
);
?>
2)查询数据表:
在项目目录Lib/Action中有IndexAction.class.php文件。重新编辑其中的index()方法:
<?php
class IndexAction extends Action {
   public function index() {
      $db=new Model('user'); //实例化模型类,参数为数据表名称,不包含前缀
      $select=$db->select(); //查询数据
      $this->assign('select',$select); //模板变量赋值
      $this->display(); //输出模板
   }
}
?>
3)数据库中数据的循环输出:
<volist name='select' id='user'>
ID:{$user.id}<br />
用户名:{$user.user}<br />
地址:{$user.address}<hr />
</volist>

6.控制器:

ThinkPHP的控制器就是模块类,通常位于项目的Lib\Action目录下面。类名就是模块名加上Action后缀,如IndexAction类表示Index模块。控制器类必须继承系统的Action基础类,这样才能确保使用Action类内置的方法。
默认生成的项目目录中,控制器IndexAction中输出的是ThinkPHP设置的内容。可以修改其中的内容,输出“个人空间欢迎你!”,代码为:
<?php
class IndexAction extends Action {
  public function index() {
     header("Content-Type:text/html;charset=utf-8");
     echo "<div style='font-weight:normal; color:blue; float:left; width:345px; text-align:center;  border:1px solid silver; background:#E8EFFF; padding:8px; font-size:14px; font-family:Tahoma'>"^_^<span style='font-weight:bold; color:red'>个人空间欢迎你!</span></div>
  }
}
?>

7.跨模块调用:

在开发过程中,经常会在当前模块调用其他模块的方法。下面通过A和R两个快捷方法完成跨模块调用。
$User=A("User"); //实例化UserAction控制器对象
$User->insert(); //调用User模块的importUser操作方法
这里的A("User")是一个快捷方法,与下面的代码等效:
import("@.Action.UserAction");
$User=new UserAction();
实际上,还有比A方法更简单的调用方法:
R("User","insert"); //远程调用UserAction控制器的insert操作方法
上面只是在当前项目中调用,如果需要在多个项目之间调用方法,代码为:
$User=A("User","Admin"); //实例化Admin项目的UserAction控制器对象
$User->insert(); //调用Admin项目UserAction控制器的insert操作方法
R("User","insert","Admin"); //远程调用Admin项目的UserAction控制器的insert方法
示例:在前台控制器中调用后台项目中的insert方法完成用户信息的添加操作
先创建tm项目根目录,在根目录下分别创建前台项目文件夹home、后台项目文件夹admin和public存储css、图片和js脚本文件。然后在tm项目根目录下编辑index.php前台入口文件和admin.php后台入口文件,代码为:
//index.php前台入口文件
<?php
define('THINK_PATH','../ThinkPHP'); //定义ThinkPHP框架路径(相对于入口文件)
define('APP_NAME','tm'); //定义项目名称
define('APP_PATH','home'); //定义项目路径
require(THINK_PATH.'/ThinkPHP.php'); //加载框架入口文件
App::run(); //实例化一个网站应用实例
?>
//admin.php后台入口文件
<?php
define('THINK_PATH','../ThinkPHP'); //定义ThinkPHP框架路径(相对于入口文件)
define('APP_NAME','tm'); //定义项目名称
define('APP_PATH','admin'); //定义项目路径
require(THINK_PATH.'/ThinkPHP.php'); //加载框架入口文件
App::run(); //实例化一个网站应用实例
?>
在浏览器中运行前后台入口文件,自动生成项目目录。定位到admin\conf目录下,编辑config.php文件,完成后台项目中数据库的配置,代码为:
<?php
return array(
   'APP_DEBUG'=>false, //关闭调试模式
   'DB_TYPE'=>'mysql', //数据库类型
   'DB_HOST'=>'localhost', //数据库服务器地址
   'DB_NAME'=>'db_database24', //数据库名称
   'DB_USER'=>'root', //数据库用户名
   'DB_PWD'=>'111', //数据库密码
   'DB_PORT'=>'3306', //数据库端口
   'DB_PREFIX'=>'think_', //数据表前缀
);
?>
定位到admin\lib\action目录下,编写后台项目的控制器。首先创建index模块,继承系统的Action基础类,定义index方法读取指定数据表中的数据,并且将查询结果赋给模板变量,最终指定模板页。IndexAction.class.php的代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     $db=new Model('user'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(); //输出模板
  }
}
?>
然后创建User模块,同样继承系统的Action基础类,定义insert方法,实例化模型类,将表单中提交的数据添加到指定的数据表中,添加成功后重定向到后台主页。UserAction.class. php的代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class UserAction extents Action{ //定义类,继承基础类
  public function insert(){ //定义方法
     $ins=new Model('user'); //实例化模型类,传递参数为没有前缀的数据表名称
     $ins->Create(); //创建数据对象
     $result=$ins->add(); //写入数据库
     $this->redirect('Index/index',5,'页面跳转中'); //页面重定向,5秒后跳转到URL地址
  }
}
?>
Action类的redirect方法可以实现页面的重定向功能,用户为:
redirect('[项目://][路由@][分组名-模块/]操作?参数1=值1[&参数N=值N]')
或者用数组方式传入参数:
redirect('[项目://][路由@][分组名-模块/]操作',array('参数1'=>'值1'[,'参数N'='值N']))
如果不定义项目和模块,就表示当前项目和模块名。
定位到admin\tpl\default目录下,首先创建index模块文件夹,编辑index操作的模板文件index.html,循环输出模板变量传递的数据。代码为:
<volist name='select' id='user'>
  <tr class="content">
<td bgcolor="#FFFFFF"> {$user.id}</td>
<td bgcolor="#FFFFFF"> {$user.user}</td>
<td bgcolor="#FFFFFF"> {$user.address}</td>
  </tr>
</volist>
然后创建User模块文件夹,编辑insert操作的模板文件index.html,创建添加用户信息的表单。代码为:
<form method="post" action="__URL__/insert">
<table width="265" border="0" cellspacing="0" cellpadding="0">
  <tr>
<td class="title" id="td">用户名:</td>
<td><input name="user" type="text" size="15" /></td>
  </tr>
  <tr>
<td class="title" id="td">密码:</td>
<td><input name="pass" type="password" size="15" /></td>
  </tr>
  <tr>
<td class="title" id="td">地址:</td>
<td><input name="address" type="text" size="20" /></td>
  </tr>
</table>
<input type="image" name="imageField" id="imageField" src="__ROOT__/public/iamges/66.gif" />
</form>
定位到home\conf目录,编辑前台项目的数据库配置文件config.php。定位到home\lib\Action目录,创建前台项目控制器Index,定义index方法查询数据库中的用户信息,并将查询结果赋给模板变量,定义insert方法,通过R快捷方法调用admin项目UserActon控制器的insert操作方法完成数据的添加操作。代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     $db=new Model('user'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(); //输出模板
  }
  public function insert(){
     $ins=R("User","insert","admin"); //远程调用admin项目UserAction控制器的insert方法
     $this->Create(); //创建数据对象
     $result=$ins->add(); //写入数据库
  }
}
?>
定位到home\tpl\default目录下,创建index模块文件夹,编辑index操作的模板文件index.html。在index.html模板文件中,创建表单提交用户注册信息,循环输出模板变量传递的数据。

8.模型:

模型的作用是封装数据库的相关逻辑,每一次执行数据库操作,都要遵循定义的数据模型规则来完成。
定义模型时,ThinkPHP要求模型类的命名是数据表名称去除前缀,并且首字母大写,然后加上模型类的后缀。例如UserTypeModel对应的数据表是think_user_type。如果命名规则与系统的约定不符,就需要设置Model类的tableName属性。示例:
protected $tableName='categories';
还有一个trueTableName是包含前缀的数据表名称,一般不需要设置,除非不按规则命名。比如:protected $trueTableName='top_depts';
还可以对数据库进行定义,当模型类对应的数据库名称与配置文件不同时需要定义。比如:
protected $dbName='top';

1)实例化模型:

在ThinkPHP2.0中,无需进行任何模型定义,可以直接进行模型的实例化操作。根据不同的模型定义,实例化模型的方法也有所不同。
⑴实例化基础模型类:
在没有定义任何模型时,可以使用下面的方法实例化一个模型类来进行操作:
$User=new Model("User");
$User->select(); //进行其他的数据操作
或者使用M快捷方法进行实例化,效果相同:
$User=M("User");
$User->select(); //进行其他的数据操作
这种方法最简单高效,因为不需要定义任何的模型类,支持跨项目调用。但因为没有自定义的模型类,无法写入相关的业务逻辑,只能完成基本的CURD操作。
⑵实例化其他模型类:
大多数情况下,需要扩展一些通用的逻辑,封装一些额外的逻辑方法。需要实例化其他模型类,可以使用:
$User=M('User','CommonModel');
等效于:
$User=new CommonModel('User');
因为系统的模型类都能够自动加载,因此不需要在实例化之前手动进行类库导入操作。模型类CommonModel必须继承Model,如果没有定义别名导入的话,需要放在项目Model下。
CommonModel类里面可以定义一些通用的逻辑方法,以省去为每一个数据表定义具体的模型类,如果项目的数据表超过100个,而且大多数都是执行基本的CURD操作,只是个别模型有一些复杂的业务逻辑需要封装,那么前面两种方式结合是不错的选择。
⑶实例化用户定义的模型类:
一个项目不可避免需要定义自身的业务逻辑实现,这就需要针对每个数据表定义一个模型类,如UserModel、InfoModel等。定义的模型类通常放到项目的lib\model目录下面。示例:
class UserModel extends Model{
   Public function myfun(){
       //添加业务逻辑
   }
}
其实,模型类还可以继承一个用户自定义的公共模型类,而不是只能继承Model类。要实例化自定义模型类,可以使用D快捷方法:
$User=D('User');
$User->select(); //进行其他的数据操作
D方法可以自动检测模型类,不存在时系统会抛出异常,同时对于已实例化过的模型,不会重复去实例化。默认的D方法只能支持调用当前项目的模型,如果需要跨项目调用,需要使用:
$User=D('User','admin'); //实例化admin项目下面的User模型
$User->select(); //进行其他的数据操作
如果启用模块分组功能,还可以使用:
$User=D('admin.User');
⑷实例化空模型类:
如果仅仅是使用原生SQL查询的话,不需要使用额外的模型类,实例化一个空模型即可进行操作。示例:
$Model=new Model(); //或者使用M快捷方法:$Mode=M();
$Model->query('SELECT * FROM think_user WHERE statue=1');
空模型也支持跨项目调用。
示例:完成数据库中用户信息和类别信息的输出
首先创建tm项目根目录,根目录下面创建项目文件夹app和public,存储css、图片和ji脚本等文件。tm根目录下编辑入口文件index.php,代码为:
<?php
define('THINK_PATH','../ThinkPHP/'); //定义ThinkPHP框架路径(相对于入口文件)
define('APP_NAME','tm'); //定义项目名称
define('APP_PATH','app'); //定义项目路径
require(THINK_PATH.'/ThinkPHP.php'); //加载框架入口文件
App::run(); //实例化一个网站应用实例
?>
浏览器中运行入口文件,自动生成项目目录。定位到app\conf目录下,编辑config.php文件,完成项目中数据库的配置,代码为:
<?php
return array(
   'APP_DEBUG'=>false, //关闭调试模式
   'DB_TYPE'=>'mysql', //数据库类型
   'DB_HOST'=>'localhost', //数据库服务器地址
   'DB_NAME'=>'db_database24', //数据库名称
   'DB_USER'=>'root', //数据库用户名
   'DB_PWD'=>'111', //数据库密码
   'DB_PORT'=>'3306', //数据库端口
   'DB_PREFIX'=>'think_', //数据表前缀
);
?>
定位到app\lib\Action目录下,编写项目的控制器。创建index模块,继承系统的Action基础类,定义index()方法,通过M方法实例化模型类,读取think_user数据表中的数据,并且将查询结果赋给模板变量,指定模板页;定义type()方法,通过M方法实例化模型类,读取类型数据表think_type中的数据,同样将查询结果赋给模板变量,指定模板页。IndexAction. class.php的代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(); //指定模板页
  }
  public function type(){
     $dba=M('Type'); //实例化模型类,参数数据表名称不包含前缀
     $select=$dba->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display('type'); //指定模板页
  }
}
?>
定位到app/tpl/default目录下,创建index模块文件夹。编辑index操作的模板文件index.html,循环输出模板变量传递的数据。代码为:
<volist name='select' id='user'>
  <tr class="content">
<td bgcolor="#FFFFFF"> {$user.id}</td>
<td bgcolor="#FFFFFF"> {$user.user}</td>
<td bgcolor="#FFFFFF"> {$user.address}</td>
  </tr>
</volist>
还要编辑type.html模板文件,循环输出类型数据库中的数据。代码为:
<volist name='select' id='user'>
  <tr class="content">
<td bgcolor="#FFFFFF"> {$type.id}</td>
<td bgcolor="#FFFFFF"> {$type.typename}</td>
<td bgcolor="#FFFFFF"> {$type.dates}</td>
  </tr>
</volist>
在Model类里面没有定义任何User表、Type表的字段信息,ThinkPHP运行时自动获取数据表的字段信息(存储于缓存文件),包括数据表的主键字段和是否自动增长等。如果需要显式获取当前数据表的字段信息,可以使用模型类的getDbField方法来获取。如果开发过程中修改了数据表的字段信息,需要清空data\_fields目录下的缓存文件,让系统重新获取更新的数据表字段信息。

2)属性访问:

ThinkPHP利用PHP5的魔术方法机制来实现属性的直接访问,这也是最常用的访问方式,通过数据对象访问。示例:
<?php
$User=new Model('User');
$User->find(1);
echo $User->name;
$User->name='ThinkPHP';
?>
还有一种属性的操作方法是通过返回数组的方式。示例:
<?php
$Type=D('Type'); //这里返回的type数据是一个数组
$type=$Type->find(1);
echo $type['name'];
$type['name']='ThinkPHP';
?>

3)连接数据库:

ThinkPHP内置抽象数据库访问层,把不同的数据库操作封装起来,只需使用公共的Db类进行操作,而无需针对不同的数据库写不同的操作代码,Db类会自动调用相应的数据库适配器来处理。目前的数据库包括MySQL、MsSQL、PgSQL、Sqlite、Oracle、Ibase以及PDO的支持,如果需要使用数据库,必须配置数据库连接信息,数据库的配置文件有多种定义方式。
⑴在项目配置文件中定义,代码为:
<?php
return array(
   'APP_DEBUG'=>false, //关闭调试模式
   'DB_TYPE'=>'mysql', //数据库类型
   'DB_HOST'=>'localhost', //数据库服务器地址
   'DB_NAME'=>'db_database24', //数据库名称
   'DB_USER'=>'root', //数据库用户名
   'DB_PWD'=>'111', //数据库密码
   'DB_PORT'=>'3306', //数据库端口
   'DB_PREFIX'=>'think_', //数据表前缀
);
?>
系统推荐使用这种方式,因为一般一个项目的数据库访问配置是相同的。使用该方法在连接数据库时系统会自动获取,无需手动连接。
可以对每个项目定义不同的数据库连接信息,还可以在调试配置文件中定义调试数据库的配置信息。如果在项目配置文件和调试配置文件中同时定义了数据库连接信息,那么在调试模式下后者生效,部署模式下前者生效。
⑵使用DSN方式在初始化Db类时传参数,代码为:
$db_dsn="mysql://root:111@127.0.0.1:3306/db_database24";
$db=new Db();
$conn=$db->getInstance($db_dsn);
该方式主要用于在控制器里面手动连接数据库,或者用于创建多个数据库连接。
⑶使用数组传参数,代码为:
$dsn= array(
   'dbms'=>'mysql',
   'username'=>'username',
   'password'=>'password',
   'hostname'=>'localhost',
   'hostport'=>'3306',
   'database'=>'dbname',
);
$db=new Db();
$conn=$db->getInstance($dsn);
该方式用于手动连接数据库或者创建多个数据库连接。
⑷在模型类里面定义参数,连接数据库,代码为:
protected $connection=array(
   'dbms'=>'mysql',
   'username'=>'root',
   'password'=>'111',
   'hostname'=>'localhost',
   'hostport'=>'3306',
   'database'=>'dbname',
);
或者使用下面的方法:
protected $connection="mysql://username:password@localhost:3306/db_name";
如果在某个模型类里面定义了connection属性,则在实例化模型对象时,会使用该数据库连接信息进行数据库连接。通常用于某些数据表位于当前数据库连接之外的其他数据库。
ThinkPHP并不是在一开始就会连接数据库,而是在有数据查询操作时才会去连接数据库。
⑸使用PDO方式连接数据库,是在项目配置文件中使用PDO连接数据库。定义的数组为:
return array(
   'DB_TYPE'=>'pdo', //数据库类型
   'DB_DSN'=>'mysql://root:111@127.0.0.1:3306/db_database24', //数据库类型不同而不同
   'DB_USER'=>'root', //数据库用户名
   'DB_PWD'=>'111', //数据库密码
   'DB_PREFIX'=>'think_', //数据表前缀
   'APP_DEBUG'=>false, //关闭调试模式
);
在使用PDO方式时,注意检查PHP环境是否开启了相关的PDO模块,同时也要确保ThinkPHP核心包中包含DbPdo.class.php文件。参数DB_DSN仅对PDO方式连接才有效。
示例:使用DSN方式与数据库连接
需要删除app\conf目录下的配置文件config.php,在app\lib\action\index目录下修改index,其中应用DSN方式连接数据库并且查询think_user表中的数据,代码为:
public function index(){
   $db_dsn="mysql://root:111@127.0.0.1:3306/db_database24";
   $db=new Db();
   $conn=$db->getInstance($db_dsn);
   $select=$conn->query('select * from think_user'); //执行查询语句
   $this=assign('select',$select); //模板变量赋值
   $this->display(); //指定模板页
}
在type()方法中,应用数组传递参数,完成数据库的连接操作,并且查询think_type表中的数据,代码为:
<?php
public function type(){
  $dsn= array(
   'dbms'=>'mysql',
   'username'=>'root',
   'password'=>'111',
   'hostname'=>'localhost',
   'hostport'=>'3306',
   'database'=>'dbname',
  );
   $db=new Db();
   $conn=$db->getInstance($dsn); //连接数据库
   $select=$conn->query('select * from think_type'); //执行查询语句
   $this=assign('select',$select); //模板变量赋值
   $this->display(); //指定模板页
}
?>

4)创建数据:

ThinkPHP可以自动根据表单数据创建数据库对象,这个优势在一个数据表的字段非常多的情况下很明显。比如,在User控制器中,定义insert()方法,首先实例化模型类,然后调用create()方法根据表单提交的POST数据创建数据对象,最后调用add()方法把创建的数据对象写入数据库。代码为:
class UserAction extends Action{
  public function insert(){ //定义方法
     $ins=new Model('user'); //实例化模型类
     $ins->create(); //创建数据对象
     $result=$ins->add(); //写入数据库
     $this->redirect('Index/index','',5,'页面跳转中'); //页面重定向
  }
}
其中的create()方法还支持其他方式提交的数据对象。例如,以数组形式提交数据,从其他的数据对象中获取的数据等,代码为:
//数组形式提交数据
$data['user']='mrsoft';
$data['address']='济南市';
$User->create($data);
//从User数据对象创建新的Member数据对象
$User=M("User"); //实例化User对象
$User->find(1); //读取数据
$Member=M("Member"); //创建Member对象
$Member->create($User);
create()方法在创建数据对象时,还实现了支持多种数据源、数据自动验证、字段类型检查和数据自动完成等。create()方法创建的数据对象是保存在内存中,并没有实际写入数据库中,直到使用add()或者save()方法,才真正将数据添加到数据库。
如果只是想简单创建一个数据对象,可以使用data()方法:
$User=M('User');
//创建数据后写入数据库
$data['user']='mrsoft';
$data['address']='济南市';
$User->data($data)->add(); //执行数据对象创建
使用data()方法创建的数据对象不会进行自动验证和过滤操作,需要自行处理。但在进行add或者save操作时,数据表中不存在的字段以及非法的数据类型是会自动过滤的。

5)连贯操作:

ThinkPHP2.0启用模型类的连贯操作方法,可以有效地提高数据存取的代码清晰度和开发效率。例如,查询一个User表的满足状态1的前5条记录并按用户id排序,代码为:
$User->where('status=1')->order('id')->limit(5)->select();
在连贯操作中,select()方法必须放到最后一个,其他的连贯操作方法调用顺序没有先后。如果不习惯使用连贯操作,还支持直接使用参数进行查询的方式,上述代码对应为:
$User->select(array('order'=>'id','where'=>'status=1','limit'=>'5'));
使用数组参数方式时,索引的名称就是连贯操作的方法名称。
不仅仅查询方法可以使用连贯操作,包括add、save、delete等方法都可以使用。示例:
$User->where('id=1')->field('id,user,address')->find();
$User->where('status=1 and id=1')->delete();
连贯操作的方法见下表:


方法

描述

where

用于查询或者更新条件的定义,参数支持字符串、数组和对象

table

定义要操作的数据表名称,可以动态改变当前操作的数据表名称,需要使用带前缀的全名,可以使用别名,参数支持字符串和数组,数组方式可以避免表名与关键字冲突。默认会自动获取当前模型对应或者定义的数据表。示例:table('think_user user')使用别名。

data

数据对象赋值,可以用于新增或者保存数据之前的数据对象赋值,参数支持对象和数组,如果是对象会自动转换成数组。也可以使用create()方法或者手动给数据对象赋值。

field

定义要查询的字段,参数支持字符串和数组。如果不指定,默认与使用field('*')等效。

order

对结果进行排序,支持对多个字段排序,参数支持字符串和数组。order(status desc,id asc)

limit

结果限制。如limit('1,10')是获取从第一条记录开始的10条记录

page

查询分页,格式page('page[,listRows]'),默认每页30条记录或limit限制的值

group

查询group支持,参数只支持字符串,示例group('user_id')

9.CURD操作:

ThinkPHP提供了灵活和方便的数据操作方法。CURD(创建、更新、读取、删除)是4个最基本的数据库操作,通常与连贯操作配合使用。

1)创建操作:

ThinkPHP中,使用add()方法完成数据的添加操作。示例:
$User=M("User");
$data['name']='ThinkPHP';
$data['email']='ThinkPHP@gmail.com';
$User->add($data);
或者使用data()方法连贯操作:
$User->data($data)->add();
如果在add之前已经创建数据对象(如使用create()或data()方法),add()方法就不需要再传入数据了。

2)读取数据:

在ThinkPHP中读取数据的方法很多,通常分为读取某个字段的值、读取数据和读取数据集。读取字段的值使用getField()方法,读取数据使用find()方法,读取数据集使用select()方法。
⑴getField()方法:
getField()方法用于读取某个字段的值。如果传入多个字段的话,可以返回一个关联数组。示例:
$User=M("User");
$nickname=$User->where('id=3')->getField('nickname'); //获取id=3的用户昵称
$list=$User->getField('id,nickname'); //获取所有用户的id和昵称
⑵select()方法:
select()方法返回值是一个二维数组。如果没有查询到任何结果,返回一个空数组。示例:
$User=M("User");
$list=$User->where('status=1')->order('create_time')->limit(10)->select();
⑶find()方法:
find()方法最多只会返回一条记录,其他方面与select()类似。示例:
$User=M("User");
$list=$User->where('status=1 and name="think"')->find();
示例:通过add()方法向数据库添加数据,然后查询数据表中用户名为mr的记录
定位到25\app\lib\action\目录,编写项目控制器,创建index模块,继承系统的action基础类,定义index()方法,通过M方法实例化模型类,应用连贯操作读取数据表中数据,并将查询结果赋给模板变量,指定模板页;定义inset()方法,通过M方法实例化模型类,应用add()方法向指定的数据表中添加数据。IndexAction.class.php的代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->where('user="mr"')->order('id desc')->limit(3)->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(); //指定模板页
  }
  public function insert(){
     $dba=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $data['user']='mr';
     $data['pass']=md5('mrsoft');
     $data['address']='济南市';
     $result=$dba->add($data); //执行添加数据
     if($result){$this->redirect('Index/index','',2,'页面跳转中');} //页面重定向
  }
}
?>
定位到app\tpl\default目录下,创建index模块文件夹。编辑index操作的模板文件index.html,应用ThinkPHP内置模板引擎中的foreach标记循环输出模板变量传递的数据。创建添加数据的表单,将数据提交到控制器的insert()方法中进行处理。代码为:
<foreach name='select' item='user'>
  <tr class="content">
    <td bgcolor="#FFFFFF"> {$user.id}</td>
    <td bgcolor="#FFFFFF"> {$user.user}</td>
    <td bgcolor="#FFFFFF"> {$user.address}</td>
  </tr>
</foreach>
<form id="form1" name="form1" method="post" action="__POST__/insert">
<input type="submit" name="button" id="button" value="数据添加" />
</form>

3)更新数据:

⑴使用save()方法更新数据,也支持连贯操作。示例:
$User=M("User");
$data['name']='ThinkPHP'; //要修改的数据对象属性赋值
$data['email']='ThinkPHP@gmail.com';
$User->where('id=5')->save($data); //根据条件保存修改的数据
save()方法在执行更新数据的操作时,如果没有设置任何更新条件,且数据对象本身也不包含主键字段,那么save方法不会更新任何数据库记录。
⑵使用data()方法创建要更新的数据对象,然后通过save()方法进行保存。示例:
$User=M("User");
$data['name']='ThinkPHP'; //要修改的数据对象属性赋值
$data['email']='ThinkPHP@gmail.com'; //要修改的数据对象属性赋值
$User->where('id=5')->data($data)->save(); //根据条件保存修改的数据
⑶针对某个字段的值,使用setField()方法更新。示例:
$User=M("User");
$User->where('id=5')->setField('name','ThinkPHP'); //更改用户的name值
如果需要更新多个字段,也可以使用setField()方法,只需要传入数组即可。示例:
$User=M("User");
$User->where('id=5')->setField(array('name','email'),array('ThinkPHP','ThinkPHP@gamil.com'));
⑷应用setInc()和setDec()方法对统计字段(通常是数字类型)中的值进行增减操作。示例:
$User=M("User");
$User->setInc('score','id=5',3); //用户的积分加3
$User->setInc('score','id=5'); //用户的积分加1
$User->setDec'score','id=5',5); //用户的积分减5
$User->setDec('score','id=5'); //用户的积分减1

4)删除数据:

ThinkPHP使用delete()方法删除数据表中的记录,也可以使用连贯操作。示例:
$User=M("User");
$User->where('id=5')->delete(); //删除id=5的用户数据
delete()方法可以删除单个或多个数据,主要取决于删除条件,也就是where()方法的参数,也可以用order()和limit()方法来限制要删除的个数。示例:
$User=M("User");
$User->where('status=0')->orser('create_time')->limit('5')->delete();
示例:应用ThinkPHP的CURD操作
定位到app\lib\action\目录下,编写项目控制器。创建index模块,继承系统的action基础类,定义index()方法,以记录的id值为条件,降幂循环输出10条记录。代码为:
<?php
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->order('id desc')->limit(10)->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(); //指定模板页
  }
}
?>
定义update()方法,根据超链接传递id值执行查询,并且将查询结果赋给指定的模板变量;然后判断表单提交的id值是否存在,如果存在则以id为条件,对指定的数据进行更新操作。代码为:
  public function update(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $select=$db->where('id='.$_GET['id'])->select(); //查询数据
     $this->assign('select',$select); //模板变量赋值
     $this->display(update); //指定模板页
     if(isset($_POST['id'])){
       $data['user']=$_POST['user'];
       $data['pass']=md5($_POST['pass']);
       $data['address']=$_POST['address'];
       $result=$db->where('id='.$_POST['id'])->save($data); //依条件保存修改的数据
       if($result){$this->redirect('Index/index','',2,'页面跳转中');} //页面重定向
     }
  }
定义delete()方法。根据超链接传递的id值,删除数据库中指定的记录数。代码为:
  public function delete(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     $result=$db->where('id='.$_GET['id'])->delete(); //删除id为5的用户数据
       if($result){$this->redirect('Index/index','',2,'数据删除成功');} //页面重定向
     }
  }
定位到app\tpl\default目录下,创建index模块文件夹。编辑index操作的模板文件index.html,应用ThinkPHP内置模板引擎中的foreach标记循环输出模板变量传递的数据。创建更新和删除超链接,将指定的id作为参数进行传递。代码为:
<foreach name='select' item='user'>
  <tr class="content">
    <td bgcolor="#FFFFFF"> {$user.id}</td>
    <td bgcolor="#FFFFFF"> {$user.user}</td>
    <td bgcolor="#FFFFFF"> {$user.address}</td>
    <td bgcolor="#FFFFFF"><a href="__URL__/update?id={$user.id}"> 更新 </a> / <a href= "__URL__/delete?id={$user.id}"> 删除 </a></td>
  </tr>
</foreach>
在index模块文件夹下,编辑update.html模板文件,创建表单,将从模板变量中读取的数据作为表单元素的默认值进行输出,用表单中数据提交到控制器的update()方法完成数据的更新操作。代码为:
<form id="form2" name="form2" method="post" action="__POST__/update">
<table width="405" border="1" cellpadding="1" cellspacing="1" bgcolor="#99CC33" bordercolor ="#FFFFFF">
<foreach name='select' item='user'>
  <tr class="content">
    <td bgcolor="#FFFFFF" class="right" width="103">名称:</td>
    <td bgcolor="#FFFFFF" width="289"><input type="hidden" name="id" id="hiddenField" value="{$user.id}" /> <input type="text" name="user" id="user" size="20" value="{$user.user}" /></td>
  </tr>
  <tr class="content">
    <td bgcolor="#FFFFFF" class="right" >密码:</td>
    <td bgcolor="#FFFFFF"> <input type="password" name="pass" size="20" value="{$user.pass}" /> </td>
  </tr>
  <tr class="content">
    <td bgcolor="#FFFFFF" class="right" >地址:</td>
    <td bgcolor="#FFFFFF"> <input type="text" name="address" size="30" value= "{$user.address}" /> </td>
  </tr>
  <tr class="content">
    <td bgcolor="#FFFFFF"> <input type="submit" name="button" id="button" value= "更新" /> </td>
  </tr>
</foreach>
</table>
</form>

10.视图:

ThinkPHP中,视图由两个部分组成:View类和模板文件。Action控制器直接与View视图类进行交互,把要输出的数据通过模板变量赋值的方式传递到视图类,而具体的输出工作则交给View视图类来进行。视图类还完成一些辅助工作,包括调用模板引擎、布局渲染、输出替换、页面Trace等功能。为了方便使用,在Action类中封装了View类的一些输出方法,如display、fetch、assign、trace和buildHtml等方法,这些方法的原型都在View视图类里面。

1)模板定义:

为了对模板文件进行有效管理,ThinkPHP对模板文件进行了目录划分,默认模板文件定义规则是:模板目录/模板主题/[分组名/]模块名/操作名+模板后缀
模板目录默认是项目下面的tpl,模板主题默认是default,模板主题功能是为了多模板切换而设计的,如果有多个模板主题,则可以使用DEFAULT_THEME参数设置默认的模板主题名。
在每个模板主题下面,是以项目的模块名为目录,然后是每个模块的具体操作模板文件,例如,User模块的add操作对应的模板文件是tpl/default/User/add.html。
模板文件的默认后缀是.html,后缀可以通过TMPL_TEMPLATE_SUFFIX类配置。
如果项目启用模块分组功能(假设User模块属于Home分组),那么默认对应的模板文件就会发生变化,为:tpl/default/Home/User/add.html。
分组功能可以通过TMPL_FILE_DEPR参数来配置,进而简化模板的目录层次。例如,设置TMPL_FILE_DEPR等于“_”,那么默认的模板文件就变成:tpl/default/Home/User_add.html。
正是因为系统有这样一种模板文件自动识别的规则,display()方法才可以无需带任何参数就输出对应的模板。

2)模板赋值:

模板赋值是在Action控制器中完成的,通过assign()方法将控制器中获取的数据赋给模板变量。例如:
$this->assign('name',$value);
如果要同时输出多个模板变量,可以使用数组的方式进行赋值。
$array=array();
$array['name']='thinkphp';
$array['email']='liu21st@gmail.com';
$array['phone']='12345678';
$this->assign($array);
这样,就可以在模板文件中同时输出name、email和phone3个变量了。

3)指定模板文件:

模板变量赋值后就需要调用模板文件来输出相关的变量,模板调用应用的是display()方法。display()方法的应用见下表:


语法格式

描述

display('操作名')

调用当前模块的其他操作模板

display('分组名:模块名:操作名')

调用其他模块的操作模板,其中的分组名可选。
如,$this->display('Admin:Member:read');

display('主题名@模块名:操作名')

调用其他主题的操作模板。
如,$this->display('Admin@User:edit');

display('模板文件名')

直接全路径输出模板。如,$this->display('./Public/menu.html');

display('模板文件名','charset')

设置模板页的编码。如,$this->display('Member:read','gbk');

display('模板文件名','charset',
'format')

设置指定模板文件的编码和格式。
如,$this->display('Member:read','utf-8','text/xml');

模板变量赋值后,在指定的模板文件中进行输出,具体的输出方法需要根据选择的模板引擎来决定。如果使用的是内置的模板引擎,要参考ThinkPHP开发完全手册模板指南中的内容;如果使用PHP本身作为模板引擎,则直接在模板文件里面输出。例如,<?php echo $name. '['.$email.''.$phone.']'; ?>

4)特殊字符串替换:

在进行模板输出之前,系统还会对模板的特殊字符串进行替换,实现模板输出的替换和过滤。这个机制可以使得模板文件的定义更加方便,默认的替换规则见下表:


特殊字符串

替换描述

../Public

被替换成当前项目的公共模板目录,通常是:/项目目录/tpl/default/public/

__PUBLIC__

被替换成当前网站的公共目录,通常是:/Public/

__TMPL__

替换成项目的模板目录,通常是:/项目目录/tpl/default/

__ROOT__

会替换成当前网站的地址(不含域名)

__APP__

替换成当前项目的URL地址(不含域名)

__URL__

替换成当前模块的URL地址(不含域名)

__ACTION__

替换成当前操作的URL地址(不含域名)

__SELF___

替换成当前页面的URL地址

这些特殊的字符串是严格区别大小写的,并且这些特殊字符串的替换规则是可以更改或者增加的。只要在项目配置文件中配置TMPL_PARSE_STRING就可以完成。如果有相同的数组索引,就会更改系统的默认规则。例如:
TMPL_PARSE_STRING=>array(
'__PUBLIC__'=>'/Common', //更改默认的__PUBLIC__替换规则
'__UPLOAD__'=>'/Public/Uploads/', //增加新的上传路径替换规则
)

11.内置模板引擎:

ThinkPHP内置了一个基于XML的性能卓越的模板引擎ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎。ThinkTemplate是一个使用XML标记库技术的模板引擎,支持两种类型的模板标记(普通标记和XML标记),使用了动态编译和缓存技术,而且支持自定义标记库。
ThinkTemplate模板引擎生成的编译文件默认存储于Runtime/Cache目录下面,以模板文件的MD5编码作为缓存文件名保存。ThinkTemplate模板引擎中的常用标记见下表:


标记

应用描述

{$name}

输出模板引擎中的变量。注意模板标记的{和$之间不能有任何的空格,否则标记无效

{$Think.server.script_name}
{$Think.session.session_id|md5}
{$Think.get.pageNumber}
{$Think.cookie.name}
{$Think.now}
{$Think.template|basename}

系统变量。除了常规变量的输出外,模板引擎还支持系统变量和系统常量,以及系统特殊变量的输出。它们的输出不需要事先赋值给某个模板变量。系统变量的输出必须以$Think.打头,并且仍然支持使用函数。

{$变量|default="默认值"}

默认值输出。如果输出的模板变量没有值,但是需要在显示时赋予一个默认值,可以使用default语法。

<include file="完整模板文件名" />
<include file="操作名" />
<include file="模块名:操作名" />
<include file="主题名@模块名:操作名" />
<include file="$变量名" />

使用Include标记来包含外部的模板文件。完整文件名的包含必须包含后缀,是服务器端包含。用变量包含,给变量赋不同的值就可以包含不同的模板文件。如果修改了包含的外部模板文件,需要把模块的缓存目录清空,否则无法生效。

<import type='js' file="Js.Util.Array" />
<import type='css' file="Css.common" />
<load href="../Public/Js/Common.js" />
<load href="../Public/Css/Common.css" />
<js href="__PUBLIC__/Js/Common.js" />
<css href="../Public/Css/common.css" />

导入文件。系统提供专门的import标记和load标记完成文件的导入操作。import标记默认的起始路径是网站的public目录,如果需要指定其他目录,可以使用basepath属性,如:<import file="Js.Util.Array" basepath= ""./common />。load标记无需指定type属性,系统会根据后缀自动判断,可用来导入js或css,可以使用特殊模板标记替换。

<volist name="list" id="vo" offset="5" length="10">
{$vo.name}
</volist>

volist标记主要用于在模板中循环输出数据集或多维数组,其中name指定变量名称,id表示循环变量,offset表示记录的起始位置,length表示记录的长度,mod控制输出的奇偶性,控制在指定的记录换行。

<foreach name="list" item="vo">
{$vo.id}
{$vo.name}
</foreach>

foreach标记用于循环输出,比volist标记简洁,优势是可以对对象进行遍历输出。volist标记通常是用于输出数组。

<switch name="变量">
<case value="值1">输出内容1</case>
<case value="值2">输出内容2</case>
<default/>默认情况
</switch>

switch标记类似于PHP的switch语句,其中的name可以使用函数以及系统变量。对于case的value属性可以支持多个条件的判断,使用|分隔。使用变量方式的情况下,不再支持多个条件的同时判断。

示例:应用ThinkPHP中提供的验证码类和分页类生成验证码并完成数据的分页输出
定位到app\lib\action\目录下,编写项目控制器。创建index模块,继承系统的action基础类,定义index()方法,验证session变量存储的验证码与用户提交的验证码是否相同,验证用户提交的用户名和密码是否正确,如果正确则将登录用户名存储到session变量中,并且将网页重定向到main.html页面。代码为:
<?php
session_start();
header("Content-Type:text/html;charset=utf-8");
class IndexAction extents Action{
  public function index(){
     if(isset($_POST['user'])){
       if(isset($_POST['user'])&&isset($_POST['pass'])&&isset($_POST['validatorCode'])){
         if($_SESSION['verify']==md5($_POST['validatorCode'])){ //验证验证码是否正确
           $db=M();
           $select=$db->query('select * from think_user where user='''.$_POST['user'].'''and pass='''.$_POST['pass'].''''); //查询数据,验证用户名和密码是否正确
           if($select){
             $_SESSION['admin']=$_POST['user']; //将登录用户名存储到session中
             $this->redirect('index/main','',2,'用户'.$_POST['user'].'登录成功!');
           }else{
             $this->redirect('index/main','',2,'用户或密码不正确!');
           }
         }else{
           $this->redirect('index/main','',2,'验证码不正确!');
       }else{
         $this->redirect('index/main','',2,'用户名与密码不能为空!');
       }
     }
     $this->display();
  }
}
?>
定义main()方法,载入分页类,完成数据库中数据的分页查询,并且将查询结果赋给模板变量。代码为:
  public function main(){
     $db=M('User'); //实例化模型类,参数数据表名称不包含前缀
     import("ORG.Util.Page"); //导入分页类
     $count=$db->count(); //统计总记录数
     //$count=$User->where('status=1)->count(); //查询满足要求的总记录数
     $Page=new Page($count,1); //实例化分页类
     $show=$Page->show(); //分页显示输出
     $list=$db->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->select();
     $this->assign('select',$list); //赋值数据集
     $this->assign('page',$show); //赋值分页输出
     $this->display(main); //指定模板页
  }
定义verify()方法,载入ThinkPHP中提供的验证码扩展类,调用buildImageVerify()方法生成验证码。代码为:
  public function verify(){
     import("ORG.Util.Image"); //载入验证码类
     image::buildImageVerify(4,5,'png','65','30','verify'); //生成验证码
  }
buildImageVerify()方法的语法为:
buildImageVerify($length,$mode,$type,$width,$height,$verifyName)
参数说明见下表:


参数

说明

length

验证码长度,默认为4位数

mode

验证字符串的类型,默认为数字,其他支持类型有0字母1数字2大写字母3小写字母4中文5混合(去掉了任意混淆的字符oOLl和数字01)

type

验证码的图片类型,默认为png

width

验证码的宽度,默认会自动根据验证码长度自动计算

height

验证码高度,默认为22

verifyName

验证码的SESSION记录名称,默认为verify

生成验证码之后,需要在模板页中通过<img src="__APP__/index/verify" />输出生成的验证码图像。在控制器中通过如下代码:
if($_SESSION['verify']!=md5($_POST['verify'])){
$this->error('验证码错误!');
}
定位到app\tpl\default目录下,创建index模块文件夹。编辑index操作的模板文件index.html,载入CSS样式文件和JavaScript文件,创建表单,完成用户登录信息的提交操作,通过img标记输出生成的验证码。代码为:
<link href="__ROOT__/public/css/style.css" rel="stylesheet" type="text/css" />
<js href="__ROOT__/public/js/check.js" />
<form name="form1" method="post" action="__URL__/index" onSubmit="return chkinput (this)">
<table width="265" border="0" cellspacing="0" cellpadding="0">
  <tr>
     <td class="title" id="td">用户名:</td>
     <td><input name="user" type="text" size="15" /></td>
  </tr>
  <tr>
     <td class="title" id="td">密码:</td>
     <td><input name="pass" type="password" size="15" /></td>
  </tr>
  <tr>
     <td class="title" id="td">验证码:</td>
     <td><input name="validatorCode" type="text" size="10" />
         <img src="__APP__/index/verify/" /> </td>
  </tr>
</table>
</form>
在index模块文件夹下,编辑main.html文件,通过模板引擎中的session标记输出当前登录的用户名,通过foreach标记循环输出模板变量传递的数据,最后输出模板变量传递的分页超链接。代码为:
<table width="405" border="1" cellspacing="1" cellpadding="1" bgcolor="#99CC33" bordercolor="#FFFFFF">
  <tr>
     <td colspan="3" bgcolor="#FFFFFF" class="title" align="center">当前登录用户:
{$Think.session.admin}</td>
  </tr>
  <foreach name='select' item='user'>
  <tr class="content">
    <td bgcolor="#FFFFFF"> {$user.id}</td>
    <td bgcolor="#FFFFFF"> {$user.user}</td>
    <td bgcolor="#FFFFFF"> {$user.address}</td>
  </tr>
</foreach>
  <tr class="content">
     <td colspan="3" bgcolor="#FFFFFF"> {$page}</td>
  </tr>
</table>
通过ThinkPHP中的扩展类生成中文验证码,关键是载入ThinkPHP\lib\ORG\Util\Image.class. php中的Image类,调用其中的GBVerify()方法,生成中文验证码。注意,GBVerify()方法中需要修改$codex=String::msubstr($code,$i,1)。

 

Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659