thinkphp程序跳转框架怎么让一段程序强制执行一遍

关于Thinkphp程序内用不了order()排序的两种解决方案 - 无忧主机
自始至终,以提供稳定、高性能的美国、香港免备案php虚拟主机产品为己任,以用户极高满意为生存价值,以产品的可靠性为生命线,以网络零中断为终身奋斗目标
的简洁实用用过的人都知晓一二,用这款程序用作网站框架来建站是非常不错的选择呢,想了解更多,请点击《》,小编透露一下这款开源程序我们无忧的也是完美支持的哦!今天无忧小编给大家说的是在这个程序内无法使用-&order($order)来排序问题,针对开发者而言,这是一个非常困扰的问题,那要怎么处理呢?
针对这句:$order = ” info.date2 desc “;降序排列的语句,可在Thinkphp程序中执行的结果却截然不同,最终结果是:order by date2 limit… desc不见了。针对这个问题,以下有两个解决方案:
方案一:语句语法有问题,在$order 里面两边不能有任何空格。
例如:$order = “info.date2 desc”;(正确)。$order = ” info.date2 desc”;(错误!)
方案二:给$order加上trim() 函数,对指定文件进行代码修改,详细步骤如下:
文件路径:.\ThinkPHP\Extend\Model\ViewModel.class.php
把文件ViewModel.class.php利用FTP工具下载到本地,并且用高级记事本进行编辑修改,需要修改的代码约在136行,这里我们给$order加上trim()保存即可,如图所示:
修改后的代码为:$array = explode(‘ ‘, trim($order));
保存后上传即可。
这个方案二是官方的一个小bug,我们可以通过添加trim来解决的哦。
PS:trim() 函数从字符串的两端删除空白字符和其他预定义字符。
无忧主机相关文章推荐阅读:
本文地址:/thinkphp/18592.html
喜欢本文或觉得本文对您有帮助,请分享给您的朋友 ^_^
无忧主机资质:(十三年旗舰品牌)
相关技术帮助文档
技术帮助文档分类thinkphp钩子的实现 - 老高的技术博客
时间: September 29, 2014
钩子概念对初学者来说可能比较抽象难懂,但是只要掌握了他的工作方式,那么自己动手写一个钩子机制也不难。
Hook这个词很有意思,以下引用自某网络词典:
Hook用作名词时意思是“钩”,转化为动词时可表示把某物弯成钩形,也可表示用弯曲的东西把某物体钩住,引申可表示为“吊”“挂”等。
作为一个程序猿,老高对钩子的解释是,他就是一个触发机制,把你的软件功能想象成一个陷阱,放到##系统流程##可能经过的路上,如果陷阱被系统踩到,就会执行你的程序,当你挂载的钩子执行完后,系统会根据你的程序的结果继续运行。
老高最早接触Hook的编程思想是源于windows,当时打dota很入迷,突然想研究一下改键的原理,于是发现了系统钩子这一说法。
改键的原理,简单地说来就是拦截系统按下键盘时的默认动作,如果需要把小键盘的7映射到Q上,就在拦截时做一个判断,如果的键码是小键盘7,就改为Q的键码,最后发送给系统修改后的键码,即完成了改键操作。
钩子机制的使用在很多系统上都有体现,如windows、wordpress、thinkphp等,由钩子实现的功能在wordpress中叫做插件,在TP中叫做行为。
老高认为,钩子在MVC模式下十分重要,他实现了在不改变源代码的前提下提升系统的灵活性,如,在文章输出前打印版权信息,在文章输出后生成二维码信息,app运行前检查用户权限,还有更多产品经理提出的变态要求,都可以
掌握了钩子的原理后,那么实现起来就很简单了,TP只花了不到100行代码就搞定了,下面我们分析一下:
首先,我们要明确一些说法。在TP中,设置陷阱的过程称为##绑定事件##,而某个事件触发的功能函数称为##行为##。
钩子应该具有的基本方法应该有:
设置钩子(导入钩子)
首先我们看看TP是怎么写的,源代码位于ThinkPHP/Library/Think/Hook.class.php,Hook类中全是静态方法,其中有唯一静态属性$tags,他是一个数组,键为绑定的事件,值为绑定的行为。
其中有两个方法可以用于绑定,前者是单个,后者是是批量。
static public function add($tag,$name) {
echo "\n";
if(!isset(self::$tags[$tag])){
self::$tags[$tag]
if(is_array($name)){
self::$tags[$tag]
array_merge(self::$tags[$tag],$name);
self::$tags[$tag][] =
static public function import($data,$recursive=true) {
if(!$recursive){ // 覆盖导入
self::$tags
array_merge(self::$tags,$data);
}else{ // 合并导入
foreach ($data as $tag=&$val){
if(!isset(self::$tags[$tag]))
self::$tags[$tag]
if(!empty($val['_overlay'])){
// 可以针对某个标签指定覆盖模式
unset($val['_overlay']);
self::$tags[$tag]
// 合并模式
self::$tags[$tag]
array_merge(self::$tags[$tag],$val);
当系统触发了某个事件,比如app_start事件,TP会找到Hook::listen方法,该方法会查找$tags中有没有绑定app_start事件的方法,然后用foreach遍历$tags属性,并执行Hook:exec方法。
static public function listen($tag, &$params=NULL) {
if(isset(self::$tags[$tag])) {
if(APP_DEBUG) {
G($tag.'Start');
trace('[ '.$tag.' ] --START--','','INFO');
foreach (self::$tags[$tag] as $name) {
APP_DEBUG && G($name.'_start');
self::exec($name, $tag,$params);
if(APP_DEBUG){
G($name.'_end');
trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');
if(false === $result) {
// 如果返回false 则中断插件执行
if(APP_DEBUG) { // 记录行为的执行日志
trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
Hook:exec方法会检查行为名称,如果包含Behavior关键字,那么入口方法必须为run方法,而执行run方法的参数在调用Hook::listen时指定。但如果不用##Behavior##关键字做配置,即将系统默认的ReadHtmlCacheBehavior改为ReadHtml,系统会报错吗?答案是会的!
如果去掉Behavior,系统就会找该类中绑定事件名称的方法,即app_begin。这样的好处是,不会强制使用run方法,一个行为可以复用了。
static public function exec($name, $tag,&$params=NULL) {
if('Behavior' == substr($name,-8) ){
// 行为扩展必须用run入口方法
= new $name();
return $addon-&$tag($params);
创作,采用
进行许可。可自由转载、引用,但需署名作者且注明文章出处。
添加新评论
: 感觉老高是我最早常逛的博客之一
我做了一个又一个博客,已经不用t...
: 请问老高,不绑定域名,用IP怎么访问wwwroot/index....
: --mtu value
--sndwnd value
: 同样的配置,在我的阿里云上的Debian正常
: 博主,向你请教一个和contab有关的问题
搬瓦工vps,设置c...
: 推荐使用 Typecho 开发版 + php 7.1.8 ,现在...
: 点保存后,出现域名+action/plugins-edit?co...
: 同样的是提示这个
: 您好那中国电信的路由器可以吗?
: 请问你是怎样解决的 我的问题和你一样当前位置: >>
ThinkPHP2.1 常见问题&开发技巧
常见问题&开发技巧 ThinkPHP2.1 常见问题&开发技巧目录1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 常见问题 8
ThinkPHP 是什么? .....................................................................................................................................8 ThinkPHP 是免费的么? .............................................................................................................................8 ThinkPHP 有 SVN 地址么?.......................................................................................................................8 ThinkPHP 支持的 PHP 版本是多少? .......................................................................................................8 ThinkPHP 有什么特殊的环境要求? .........................................................................................................9 ThinkPHP 和其他框架比较有什么特色? .................................................................................................9 ThinkPHP 里面的 MVC 对应哪些?....................................................................................................... 10 什么是 CURD? ......................................................................................................................................... 10 什么是单一入口?...................................................................................................................................... 10 什么是系统基类库?.................................................................................................................................. 11 ThinkPHP 是低耦合的框架么? .............................................................................................................. 11 ThinkPHP 可以使用第三方的类库或者类库包么?.............................................................................. 12 ThinkPHP 的类库一定要使用.class.php 后缀么? .............................................................................. 12 可以让编译缓存保留空白和注释或者关闭编译缓存么? ..................................................................... 12 ThinkPHP 是如何识别和解析 URL 的? ................................................................................................ 13 ThinkPHP 如果获取带有/的 get 参数? ................................................................................................ 13 出现缓存文件写入失败是什么原因? ..................................................................................................... 13 ThinkPHP 里面必须给每个操作定义方法么? ...................................................................................... 14 ThinkPHP 可以支持多主题吗? .............................................................................................................. 14 ThinkPHP 的 display 方法是如何定位模板文件的? .......................................................................... 14 ThinkPHP 的控制器名称是否一定要和数据表一致?.......................................................................... 15 如何让网站默认访问 Blog 模块而不是 Index 模块 .............................................................................. 15 入口文件里面的 THINK_PATH 应该如何定义? .................................................................................. 152 ThinkPHP2.1 常见问题&开发技巧1.24 1.25 1.26 1.27 1.28 1.29 1.30 1.31 1.32 1.33 1.34 1.35 1.36 1.37 1.38 1.39 1.40 1.41 1.42 1.43 1.44 1.45 1.46 1.47 1.48 1.49入口文件中的项目路径应该如何定义? ................................................................................................. 16 ThinkPHP 是否支持 PATHINFO? ........................................................................................................ 16 ThinkPHP 必须要求服务器支持 PAHTINFO 么? ............................................................................... 17 ThinkPHP 怎么实现动态的 URL 解析? ................................................................................................ 17 ThinkPHP 是否支持路由? ...................................................................................................................... 17 ThinkPHP 是否支持 SEO 优化? ............................................................................................................ 18 ThinkPHP 的验证码为何无法显示? ...................................................................................................... 18 ThinkPHP 可以同时执行多个操作么? .................................................................................................. 18 ThinkPHP 可以支持哪些数据库? .......................................................................................................... 19 ThinkPHP 是否会自动关闭数据库连接? .............................................................................................. 19 ThinkPHP 的模型类的名称必须要和数据表一致么?.......................................................................... 19 ThinkPHP 是否支持跨数据库和跨服务器操作?.................................................................................. 20 为什么修改了数据表的字段后无法识别新的字段? ............................................................................. 20 可以在模型类里面定义数据表的字段信息吗? ..................................................................................... 20 ThinkPHP 的表单字段是否一定要和数据表的字段保持一致? ......................................................... 21 ThinkPHP 是否支持分布式数据库? ...................................................................................................... 21 ThinkPHP 是否支持同时多个数据库连接? .......................................................................................... 22 模型的自动验证和自动完成有什么区别? ............................................................................................. 23 自动验证的 Callback 和 function 方式定义的区别是什么? ............................................................. 23 ThinkPHP 的视图模型是什么含义? ...................................................................................................... 23 ThinkPHP 的配置文件采用什么格式? .................................................................................................. 24 ThinkPHP 的配置文件的优先级别是什么? .......................................................................................... 24 ThinkPHP 的惯例配置有哪些参数? ...................................................................................................... 25 ThinkPHP 的模块配置的名称格式是什么? .......................................................................................... 25 ThinkPHP 的命名规范有哪些? .............................................................................................................. 25 如何关闭 ThinkPHP 的模板缓存? ......................................................................................................... 263 ThinkPHP2.1 常见问题&开发技巧1.50 1.51 1.52 1.53 1.54 1.55 1.56 1.57 1.58 1.59 1.60 1.61 1.62 1.63 1.64 1.65 1.66 1.67 1.68 1.69 1.70 1.71 1.72 1.73 1.74 1.75ThinkPHP 的模板如何使用 PHP 本身作为模板引擎?........................................................................ 27 ThinkPHP 的模板可以使用第三方的模板引擎吗?.............................................................................. 27 如何输出其他模块的操作模板? ............................................................................................................. 28 模板文件开头的&taglib name=’html’ /&是什么意思?.............................................................. 28 编辑器无法识别 XML 标签,模板标签的定界符可以定制吗? .......................................................... 28 如何获取模板输出的内容? ..................................................................................................................... 29 模板文件里面经常使用的__URL__和 __APP__有什么用? .................................................................. 29 如何在模板文件中直接输出系统变量和常量? ..................................................................................... 30 ThinkPHP 调试起来方便吗? .................................................................................................................. 30 ThinkPHP 的页面 Trace 是什么作用?.................................................................................................. 31 怎么查看上次执行的查询语句是什么? ................................................................................................. 31 经常看到的 D 方法和 C 方法是什么意思? ........................................................................................... 32 ThinkPHP 是否可以支持 Jquery 和其他的 JS 框架? ......................................................................... 32 如何采用子目录的方式缓存数据? ......................................................................................................... 33 使用 ThinkPHP 的过程中为什么总是容易发生乱码?......................................................................... 33 使用 ThinkPHP 开发一定要使用 UTF8 编码吗? ................................................................................. 33 如何用 S 方法删除缓存? ......................................................................................................................... 34 如何设置永久缓存某个数据? ................................................................................................................. 34 ThinkPHP 是怎么进行安全过滤的? ...................................................................................................... 34 什么是 MVC? ........................................................................................................................................... 35 如何快速架构项目?.................................................................................................................................. 36 为何无法更新数据表字段? ..................................................................................................................... 36 用 M 方法或者 D 方法实例化模型有什么区别? .................................................................................. 37 修改了 Common 函数文件,怎么运行的时候没有任何变化? ......................................................... 37 如何添加自己的函数库? ......................................................................................................................... 37 如何更新同字段名的多条记录? ............................................................................................................. 384 ThinkPHP2.1 常见问题&开发技巧1.76 1.77 1.78 1.79 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 2.20 2.21为何 RBAC 改了路径就没有权限了?..................................................................................................... 38 为什么$this-&error() 和$this-&success()跳转同一个模板文件? ................................................... 39 怎么输出原生查询的结果? ..................................................................................................................... 39 如何获得上一步插入记录的 id? ............................................................................................................. 39 开发技巧 40创建数据对象后的更改.............................................................................................................................. 40 定义实际的数据表名称.............................................................................................................................. 41 定义实际的数据库名称.............................................................................................................................. 41 获取个别字段的值...................................................................................................................................... 41 设置字段别名.............................................................................................................................................. 43 字段的表达式更新...................................................................................................................................... 44 字段的动态查询.......................................................................................................................................... 44 针对主键的几个特殊用法 ......................................................................................................................... 45 获取当前 Action 的名称 ........................................................................................................................... 47 获取当前 Model 的名称 ........................................................................................................................... 47 原生 SQL 和数据表替换 ............................................................................................................................ 48 快速切换到其他的数据库 ......................................................................................................................... 49 利用别名快速加载类库.............................................................................................................................. 50 自动加载类库.............................................................................................................................................. 51 文件哈希子目录缓存.................................................................................................................................. 52 使用正则表达式进行自动验证 ................................................................................................................. 52 如何在表单里面隐藏字段名称 ................................................................................................................. 55 不创建模型类如何自动验证 ..................................................................................................................... 55 模型不需要数据库怎么定义 ..................................................................................................................... 57 如何实现延迟更新...................................................................................................................................... 57 如何避免某个字段被修改? ..................................................................................................................... 585 ThinkPHP2.1 常见问题&开发技巧2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.35 2.36 2.37 2.38 2.39 2.40 2.41 2.42 2.43 2.44 2.45 2.46 2.47如何使用乐观锁功能.................................................................................................................................. 58 判断当前操作的请求类型 ......................................................................................................................... 60 如何隐藏 URL 地址里面的 index.php? .................................................................................................. 61 巧用空操作实现用户动态 URL ................................................................................................................. 62 利用路由实现用户动态 URL ..................................................................................................................... 63 巧用伪静态实现网站语言伪装 ................................................................................................................. 65 避免 URL 目录过深的技巧 ........................................................................................................................ 66 添加目录安全文件...................................................................................................................................... 67 如何在模板文件中使用运算符 ................................................................................................................. 68 避免 JS 代码被模板解析............................................................................................................................ 69 模型单独设置数据表的前缀 ..................................................................................................................... 69 巧用模型的表后缀实现多语言数据存储 ................................................................................................. 70 空间不支持 PATHINFO 的处理 ............................................................................................................... 72 在 Nginx 的下如何支持 PATHINFO ...................................................................................................... 73 如何在 TP 中支持 Amf 开发 ..................................................................................................................... 74 如何在 TP 中支持 Phprpc 开发 ............................................................................................................... 74 利用分组的二级域名部署功能 ................................................................................................................. 75 利用 ALLINONE 模式提高性能 ............................................................................................................... 76 设置默认时区.............................................................................................................................................. 76 增加模板替换字符串.................................................................................................................................. 77 如何在页面输出__PUBLIC__ .................................................................................................................... 78 巧用公共文件检测浏览器缓存 ................................................................................................................. 79 使用 U 方法支持分组................................................................................................................................. 79 如何定制网站的错误页面 ......................................................................................................................... 80 改变运行时间的显示位置 ......................................................................................................................... 81 定制页面 Trace 显示信息 ......................................................................................................................... 816 ThinkPHP2.1 常见问题&开发技巧2.48 2.49 2.50 2.51 2.52 2.53 2.54 2.55 3 3.1如何支持 WML........................................................................................................................................... 82 利用初始化方法判断登录 ......................................................................................................................... 83 如何实现上传文件子目录保存 ................................................................................................................. 84 图片上传如何实现自动缩略图 ................................................................................................................. 84 巧用回调方法实现数组存储 ..................................................................................................................... 85 定制 list 标签的字段列表 .......................................................................................................................... 87 定制 list 标签的操作列表 .......................................................................................................................... 89 主键不是 id 的时候 list 标签如何输出 .................................................................................................... 90 推荐阅读 92.htaccess 文件使用手册 ........................................................................................................................... 927 ThinkPHP2.1 常见问题&开发技巧1常见问题1.1 ThinkPHP 是什么?ThinkPHP 是基于 MVC 模式的面向对象的 PHP 开发框架,基于 Apache2 开源协议发布,属于轻量级的中文 PHP 开发框架,提供 WEB 应用开发的快速解决方案。ThinkPHP 不是博客系统,也不 是 CMS 系统,但是可以开发出任何类似博客或者 CMS 系统的应用出来。1.2 ThinkPHP 是免费的么?ThinkPHP 基于 Apache2 开源协议( http://www.apache.org/licenses/LICENSE-2.0)发布, 并且永久免费下载和使用,并且对商业友好。1.3 ThinkPHP 有 SVN 地址么?ThinkPHP 有在 Google 项目申请注册,SVN 地址: 完整版本 /svn/trunk 核心版本 /svn/trunk/ThinkPHP1.4 ThinkPHP 支持的 PHP 版本是多少?ThinkPHP 2.*版本需要 PHP5.0(建议 5.2.0 以上版本)版本的支持。8 ThinkPHP2.1 常见问题&开发技巧1.5 ThinkPHP 有什么特殊的环境要求?ThinkPHP 对服务器和操作系统环境没有太多要求,经过我们的测试在 Apache、IIS,甚至在 Nignx 下面都可以运行。并且核心框架没有依赖任何 PHP 的其他模块,只有在应用的时候才需要根据自 己的需求来考虑是否需要额外的环境要求。1.6 ThinkPHP 和其他框架比较有什么特色?ThinkPHP 的主要特色是官方团队花费五年的时间和积累和打造的为用户考虑的众多细节,包 括架构、功能和使用方面的一系列特点,并且功能全面、独具创新、文档齐全,是 WEB 应用开发的最佳 实践框架。不但融合了众多不同语言和领域的优秀框架的思想,也给出了自己独有的功能创新和用户开 发体验。其类库导入、项目编译、视图模型、ORM 实现、动态查询、分布式和多数据库支持、静态缓存、 配置文件、缓存机制、模型自动验证和自动完成、空模块和空操作、权限认证、URL 模式等功能较国内 外的框架有明显的不同和创新,内置了独立开发的基于 XML 和标签库的 PHP 模板引擎作为更是同类框 架的首创。另外的优势就是本地化的文档和社区优势,官方提供有完全开发手册和在线手册。9 ThinkPHP2.1 常见问题&开发技巧1.7 ThinkPHP 里面的 MVC 对应哪些?在 ThinkPHP 里面,M 是指模型类 Model V 是指模板文件 C 主要是指 Action 控制器。之所以 说是主要,是因为有一些额外的控制操作是在核心控制器 App 中处理方面的,严格来说,他们也属于 C 的范畴。1.8 什么是 CURD?CRUD 是一个数据库技术中的缩写词,一般的项目开发的各种参数的基本功能都是 CURD。 它代表创建(Create)、读取(Read)、更新(Update)和删除(Delete)操作。CRUD 定义了用于 处理数据的基本原子操作。.1.9 什么是单一入口?传统的模式下面,当 WEB 服务器收到一个 http 请求时,会解析该请求以确定要访问哪一个文 件。例如 /news.php 的解析结果就是要求 web 服务器解析 news.php 文件,并返 回结果给浏览器。而单一入口则是无论什么功能操作都请求同一个 index.php 文件,然后根据 url 参数 进行了第二次解析,以确定要访问的文件和操作,而 index.php 通常被称为入口文件。注意,单一入口 并不代表网站是唯一入口的。10 ThinkPHP2.1 常见问题&开发技巧1.10什么是系统基类库?基类库位于框架系统目录下面的 Lib 目录,这些类库除了框架运行所需要的核心类库,还包括 网站和项目开发过程中经常会用到的常用工具类。目前主要包含 Think 核心类库、ORG 扩展类库、Com 扩展类库,其中 Think 核心基类库的作用是完成框架的通用性开发而必须的基础类和常用工具类等,包 含有: Think.Core 核心类库包 Think.Db 数据库类库包 Think.Util 系统工具类库包 Think.Template 内置模板引擎类库包 Think.Exception 异常处理类库包 ORG 和 Com 类库包主要用于基类库的扩展,ORG 类库包主要是第三方的公共类库,而 Com 类库 包通常用于企业类库,或者多年的开发经验而积累形成的类库包,主要是内部或者局部范围使用。默认 情况下,ORG 类库包是已经有创建的,并且也包含了一些常用的类库,而 Com 类库包是需要自己来创 建的,因此你在系统的 Lib 目录下面是看不到 Com 目录的。1.11ThinkPHP 是低耦合的框架么?可以这么认为,ThinkPHP 的核心(类库)是高耦合的,这是出于效率和机制的考虑,因为 ThinkPHP 的惯例配置贯穿始终,因此,ThinkPHP 的核心是不可拆分的(这里指的核心是指 Think 基类 库),但是保留了扩展机制。而扩展类库是低耦合的或者可替换的。11 ThinkPHP2.1 常见问题&开发技巧1.12ThinkPHP 可以使用第三方的类库或者类库包么?ThinkPHP 完全可以支持第三方的类库引入,放入 Vendor 目录后即可直接使用。导入方式参 考下面的方式:Vendor('Zend.Filter.Dir'); 利用这个机制,我们完全可以把其他框架的低耦合类库直接 在 ThinkPHP 中调用。1.13ThinkPHP 的类库一定要使用.class.php 后缀么?ThinkPHP 的默认规范是类库名和文件名一致(包括大小写),并且后缀使用.class.php,这是 为了更加方便系统内置的类库导入(import)机制。如果你的后缀使用.php 的话,一样可以通过参数控 制导入,并不会影响正常使用。1.14可以让编译缓存保留空白和注释或者关闭编译缓存么?默认的情况下,为了缩小文件大小,系统对核心编译缓存和项目编译缓存文件去掉了空白和注 释,但是可以通过如下的配置保留,以进行更加方便的调试定位。在入口文件里面添加下面的常量定义 即可: define('STRIP_RUNTIME_SPACE',false); 还可以关闭核心编译缓存(同样在入口文件里面定义) defined('CACHE_RUNTIME',false);12 ThinkPHP2.1 常见问题&开发技巧如果开启了项目的调试模式的话,也会关闭项目的编译缓存。1.15ThinkPHP 是如何识别和解析 URL 的?ThinkPHP 里面会根据当前的 URL 来分析要执行的模块和操作。这个分析工作由 URL 调度器来 实现,官方内置了 Dispatcher 类来完成该调度。在 Dispatcher 调度器中,会根据 http://domainName/appName/moduleName/actionName/params 来获取当前需要执行的项目(appName)、模块(moduleName)和操作(actionName),在 某些情况下,appName 可以不需要(通常是网站的首页,因为项目名称可以在入口文件中指定,这种 情况下,appName 就会被入口文件替代),另外针对不同的 URL 模式设置系统会进行不同的智能识别。1.16ThinkPHP 如果获取带有/的 get 参数?在默认的情况下,TP 采用的 PATHINFO URL 模式,并且默认分隔符是”/”,这个时候,如果 传递带有“/”的参数就会发生混淆,处理方法是对传人的 get 参数进行处理,例如对参数进行 url_encode、rawurlencode 或者 base64_encode 编码处理,或者更改默认的 PATHINFO 分隔符。1.17出现缓存文件写入失败是什么原因?检查下缓存目录是否具有可写权限,TP 默认情况下,要求 Runtime 目录及其子目录都具有可 写权限。13 ThinkPHP2.1 常见问题&开发技巧1.18ThinkPHP 里面必须给每个操作定义方法么?对于没有任何业务逻辑的操作我们可以直接定义模板文件即可,这种情况下无需定义操作方法, 系统会直接渲染模板文件输出。1.19ThinkPHP 可以支持多主题吗?ThinkPHP 支持主题的概念,默认的是 default 主题,如果需要增加新的主题,只需要在项目目 录下面的 Tpl 目录下面创建新的主题目录即可,然后在项目配置中设置默认的主题名称: 'DEFAULT_THEME' =& 'new' 也可以在程序中动态改变当前的模板主题,例如根据不同用户设置不同的皮肤模板风格等等。1.20ThinkPHP 的 display 方法是如何定位模板文件的?ThinkPHP 的模板输出通常只需要写一个空白的 display 方法 $this-&display(); 该方法没有定义任何要输出的模板文件,但是系统会根据默认的规则去寻找模板目录下面的以模块 目录的操作模板文件。例如,假如 display 方法位于 UserAction 类的 add 操作方法,那么系统会自动 寻找模板目录下面的 User/add.html 模板文件,这就是为什么空的 display 方法也能输出模板的原因。 当然,display 方法一样可以支持参数输出,而且有很多的规则。14 ThinkPHP2.1 常见问题&开发技巧1.21ThinkPHP 的控制器名称是否一定要和数据表一致?ThinkPHP 的控制器(Action)类和数据表完全没有关系,怎么命名取决于你的项目如何进行 模块化的设计。1.22如何让网站默认访问 Blog 模块而不是 Index 模块可以在项目配置文件里面配置: 'DEFAULT_MODULE'=&'Blog' 就可以改变默认的模块访问。1.23入口文件里面的 THINK_PATH 应该如何定义?入口文件里面的 THINK_PATH 主要用于定位 ThinkPHP 系统目录的位置,可以使用相对路径 或者决定路径都可以,例如: define('THINK_PATH', '../ThinkPHP'); 或者 define('THINK_PATH', '/Home/ThinkPHP'); 如果该位置已经加入 PHP 的搜索路径,可以无需定义。也就是说,框架的系统目录可以随意放置, 哪怕是不在 WEB 访问路径下面。 或者干脆不用定义 THINK_PATH,而是直接包含框架的系统入口文件,例如把原来的:15 ThinkPHP2.1 常见问题&开发技巧define('THINK_PATH', '../ThinkPHP'); require(THINK_PATH.&/ThinkPHP.php&); 改成: require (&../ThinkPHP/ThinkPHP.php&);1.24入口文件中的项目路径应该如何定义?入口文件里面的项目路径指的是项目目录(也就是项目 Lib、Conf 所在的目录)所在的路径, 和项目的入口文件的位置没有关系,原则上,项目的入口文件可以随意摆放,只要是在 WEB 访问目录下 面即可。只是随着项目入口文件的位置不同,项目路径的定义也会变化。项目路径的定义和 THINK_PATH 定义一样,采用相对路径和绝对路径都可以。1.25ThinkPHP 是否支持 PATHINFO?ThinkPHP 可以完美支持 PATHINFO,并且可以配置 PATHINFO 方式的 URL 分隔符,例如可 以支持下面的 URL http://domainName/User/read/id/1 http://domainName/User-read-id-116 ThinkPHP2.1 常见问题&开发技巧1.26ThinkPHP 必须要求服务器支持 PAHTINFO 么?ThinkPHP 除了 PATHINFO 模式外,还可以支持普通 URL 模式和兼容 URL 模式,这两种模式 都可以用于不支持 PATHINFO 的服务器环境。例如,原来的 URL 可能变化为: 普通 URL 模式 :http://domainName/?m=User&a=read&id=1 兼容 URL 模式 :http://domainName/?s=/User/read/id/1 例如对于 Nginx 环境和个别 FASTCGI 模式(国外的空间居多)下面有可能不支持 PATHINFO 模式, 官方建议采用兼容 URL 模式进行处理,这样的方便之处是可以和 PATHINFO 模式实现配置切换,而不 需更改任何模板文件。1.27ThinkPHP 怎么实现动态的 URL 解析?例如 http://domainName/User/3 这样的 URL 地址,因为 User 后面的 id 是一个可变的参数, 所以无法当成一个普通的操作名称来解析,ThinkPHP 里面有多种方案可以实现类似的 URL,包括: 使用 URL 路由功能把 User/3 路由到 User 模块的 read 操作 使用空模块和空操作功能 第二种方案还可以实现 http://domainName/3 这样的 URL1.28ThinkPHP 是否支持路由?ThinkPHP 可以很好的支持路由功能,包括简单路由和正则路由支持,可以通过配置来支持实 现不同的功能,例如:17 ThinkPHP2.1 常见问题&开发技巧http://domainName/Blog/3 http://domainName/Blog/2008/12/1.29ThinkPHP 是否支持 SEO 优化?ThinkPHP 可以针对 URL 进行定制 在一定程度上可以满足 SEO 对 URL 设计的要求。例如,可 以实现类似下面的 URL 地址: http://domainName/blog/3 http://domainName/blog-3.html http://domainName/blog_2008_121.30ThinkPHP 的验证码为何无法显示?验证码无法正常显示,通常包括几个原因: 检查你的 GD 库模块是否开启; 检查你的程序在验证码之前是否有任何输出; 如果使用了 UTF8 编码,请确保删除 UTF8 的 BOM 信息头;1.31ThinkPHP 可以同时执行多个操作么?ThinkPHP 的操作链功能可以按照顺序执行多个定义好的操作,其访问格式是: http://domainName/appName/User/action1:action2:action3/ 上面的访问地址可以同时执行 User 模块的 action1、acton2 和 action3 操作方法。18 ThinkPHP2.1 常见问题&开发技巧1.32ThinkPHP 可以支持哪些数据库?ThinkPHP 可以支持的数据库包括 Mysql、MsSQL、PgSQL、Sqlite、Oracle、Ibase,更多 的数据库支持还可以使用 PDO 方式连接。1.33ThinkPHP 是否会自动关闭数据库连接?ThinkPHP 在完成数据操作后,会自动关闭数据库连接,这个操作是在 Db 类的析构方法里面 完成的,如果你需要更加及时的关闭数据库连接。1.34ThinkPHP 的模型类的名称必须要和数据表一致么?ThinkPHP 的模型(Model)类和数据表可以不一致,你只要设置模型类的 tableName 或者 trueTableName 属性即可。默认情况下保持和数据表一致的定义是为了让系统可以自动识别对应的数据 表。系统可以自动识别的模型名称定义包括下面两种方式(假设数据表的前缀定义是 think_): 模型名和数据表名一致(不包括数据表的前缀和后缀),例如:UserModel 可以字段对应数据表 think_user 模型名采用驼峰法命名,例如:UserTypeModel 可以自动对应数据表 think_user_type19 ThinkPHP2.1 常见问题&开发技巧1.35ThinkPHP 是否支持跨数据库和跨服务器操作?ThinkPHP 的模型类可以定义单独的数据库名称,查询的时候会自动加上当前所属的数据库。 还可以给模型定义单独的数据库连接,可以使得某个模型可以支持不同的服务器上面的不同数据库类型。 要注意的是跨服务器的查询要避免使用视图和 JOIN 查询。1.36为什么修改了数据表的字段后无法识别新的字段?ThinkPHP 会对数据表的字段信息进行缓存,如果你在开发过程中修改了数据表的字段而又没 有开启调试模式的话,会发生对应的字段无法保存的情况,这个时候需要删除 Runtime/Data/_fields 目 录下面的字段缓存文件,在调试模式下面会自动关闭数据表字段缓存。 你也可以自己在项目配置里面添加: 'DB_FIELDS_CACHE'=&false, // 不缓存数据表的字段信息1.37可以在模型类里面定义数据表的字段信息吗?答案是肯定的,如果不希望 ThinkPHP 自动去获取数据表的字段信息并缓存,可以直接在模型 类里面定义好相关的字段信息,这样的好处是可以节省文件读取的 IO 开销,建议在部署的时候可以使用, 缺点是每次更改数据库的字段都必须手动更新。手动定义的格式是在模型类添加下面的格式定义: protected $fields = array( 'id', 'username','email', 'age', // 字段信息20 ThinkPHP2.1 常见问题&开发技巧'_pk'=&'id', '_autoInc'=&true )// 主键名称 // 主键是否属于自动增长类型1.38ThinkPHP 的表单字段是否一定要和数据表的字段保持一致?默认情况下,表单提交的字段名要和数据表的字段保持一致,否则无法写入到数据表里面。但 是,系统提供了表单字段映射功能,可以给数据表的字段定义表单映射,来避免用户直接知道数据表的 字段设计。1.39ThinkPHP 是否支持分布式数据库?ThinkPHP 内置支持分布式数据库的定义和查询,包括读写分离。可以参考如下的项目配置: 在项目配置文件里面定义 Return array( 'DB_DEPLOY_TYPE '=&1, // 启用分布式数据库支持 'DB_RW_SEPARATE'=&true, // 设置读写操作分离 'DB_TYPE'=& 'mysql', // 分布式数据库的类型必须相同 'DB_HOST'=& '192.168.0.1,192.168.0.2', // 分布式数据库的地址'DB_NAME'=&'thinkphp', // 如果相同可以不用定义多个21 ThinkPHP2.1 常见问题&开发技巧'DB_USER'=&'user1,user2', 'DB_PWD'=&'pwd1,pwd2', 'DB_PORT'=&'3306', 'DB_PREFIX'=&'think_', …… 其它项目配置参数 ); 但是数据库的数据同步不是由框架自动完成,而是交给数据库本身来实现。1.40ThinkPHP 是否支持同时多个数据库连接?在系统的配置数据库连接之外,ThinkPHP 可以良好的支持多个数据库的连接和切换。这个连 接是动态的,在程序里面实现。例如: $User = D(&User&); // 创建多个数据库连接的 DSN $myConnect1 = 'mysql://username:passwd@192.168.1.1/DbName1'; $myConnect2 = 'pgsql://username:passwd@192.168.1.2/DbName2'; // 增加数据库连接 第二个参数表示连接的序号 // 注意内置的数据库连接序号是 0,所以额外的数据库连接序号应该从 1 开始 // 可以同时增加多个数据库连接 $User-&addConnect($myConnect1,1);22 ThinkPHP2.1 常见问题&开发技巧$User-&addConnect($myConnect2,2); // 切换当前要操作的数据库到连接 2 $User-&switchConnect(2); // 关闭连接序号为 2 的数据库连接 $User-&closeConnect(2);1.41模型的自动验证和自动完成有什么区别?模型的自动验证主要是对表单提交的数据进行验证是否符号要求,自动完成是对表单没有的数 据进行添加,或者对提交的数据进行过滤,两者的配合可以保证写入数据库的数据是符合要求的数据信 息。这两个功能需要数据的创建是使用 Create 方法创建的,如果没有使用 Create 方法创建数据对象的 话,可以使用高级模型提供的字段自动过滤功能。1.42自动验证的 Callback 和 function 方式定义的区别是什么?callback 表示是模型的方法调用, function 表示是函数调用1.43ThinkPHP 的视图模型是什么含义?ThinkPHP 在 ORM 模型里面模拟实现了数据库的视图模型,该功能可以用于多表查询。和数 据库的视图概念区别是视图模型修改比较方便,无需修改数据库本身。而且不需要数据库的视图支持,23 ThinkPHP2.1 常见问题&开发技巧这是 ThinkPHP 框架的亮点之一。下面定义了一个 Blog 视图模型,我们通过创建 BlogView 模型来快速 读取一个包含了 User 名称和类别名称的 Blog 记录(集),其查询方式和普通模型一样。 class BlogViewModel extends Model { protected $viewModel = protected $viewFields = array( 'Category'=&array('title'=&'categoryName'), 'User'=&array('name'=&'userName'), 'Blog'=&array('id','name','title'), ); }1.44ThinkPHP 的配置文件采用什么格式?ThinkPHP 的配置文件采用效率最高的 PHP 返回数组方式,不需要额外的解析过程。只要会使 用 PHP 的数组,就会定义 ThinkPHP 的配置文件。1.45ThinkPHP 的配置文件的优先级别是什么?ThinkPHP 中配置文件的优先顺序从低到高依次是:(在没有生效的前提下)24 ThinkPHP2.1 常见问题&开发技巧惯例配置 ? 项目配置 ? 调试配置 ? 模块配置 ? 操作(动态)配置1.46ThinkPHP 的惯例配置有哪些参数?ThinkPHP 的系统惯例配置文件在系统目录的 Common\convention.php,里面列出了系统的 所有配置参数以及默认配置,并且有详细的注释,具体也可以参考官方的配置指南和参考文档。1.47ThinkPHP 的模块配置的名称格式是什么?ThinkPHP 的模块配置文件位于项目的 Conf 目录下面,命名规范是: 模块名称(小写)_config.php1.48ThinkPHP 的命名规范有哪些?ThinkPHP 的开发过程中尽量遵循下面的文件命名规范: 类文件都是以.class.php 为后缀(这里是指的 ThinkPHP 内部使用的类库文件,不代表外部加载的 类库文件),使用驼峰法命名,并且首字母大写,例如 DbMysql.class.php。 函数、配置文件等其他类库文件之外的一般是以.php 为后缀(第三方引入的不做要求)。 确保文件的命名和调用大小写一致,是由于在类 Unix 系统上面,对大小写是敏感的(而 ThinkPHP 在调试模式下面,即使在 Windows 平台也会严格检查大小写)。25 ThinkPHP2.1 常见问题&开发技巧类名和文件名一致(包括上面说的大小写一致),例如 UserAction 类的文件命名是 UserAction.class.php, InfoModel 类的文件名是 InfoModel.class.php, 函数的命名使用小写字母和下划线的方式,例如 get_client_ip Action 控制器类以 Action 为后缀,例如 UserAction、InfoAction 模型类以 Model 为后缀,例如 UserModel、InfoModel 方法的命名使用驼峰法,并且首字母小写,例如 getUserName 属性的命名使用驼峰法,并且首字母小写,例如 tableName 以双下划线“__”打头的函数或方法作为魔法方法,例如 __call 和 __autoload 常量以大写字母和下划线命名,例如 HAS_ONE 和 MANY_TO_MANY 配置参数以大写字母和下划线命名,例如 HTML_CACHE_ON 语言变量以大写字母和下划线命名,例如 MY_LANG,以下划线打头的语言变量通常用于系统语言 变量,例如 _CLASS_NOT_EXIST_。 数据表和字段采用小写加下划线方式命名,例如 think_user 和 user_name1.49如何关闭 ThinkPHP 的模板缓存?ThinkPHP 的模板缓存是无法关闭的,因为内置的模板引擎是一个编译型的模板引擎,必须经 过编译后生成一个可执行的缓存文件才能被执行。但是可以设置缓存的有效期,例如设置 'TMPL_CACHE_TIME' =&3,26// 模板缓存有效期 -1 永久 单位为秒 ThinkPHP2.1 常见问题&开发技巧这样,每隔 3 秒系统会自动重新编译模板文件。默认的配置是-1 表示永久缓存,除非模板文件有改 动,模板文件一旦有改动会自动重新编译,如果是包含进来的外部文件有修改,系统是不会自动重新编 译的。1.50ThinkPHP 的模板如何使用 PHP 本身作为模板引擎?ThinkPHP 内置的模板引擎也支持直接在模板文件里面使用 PHP 代码,如果你不想使用任何模 板引擎和标签的话,可以配置模板引擎类型为 PHP 就可以完全使用 php 本身作为框架的模板引擎,在项 目配置里面添加: 'TMPL_ENGINE_TYPE' =&'php'1.51ThinkPHP 的模板可以使用第三方的模板引擎吗?ThinkPHP 框架允许你使用第三方的模版引擎。目前官方已经提供了 Smarty 模版引擎的插件, 已经有人给 ThinkPHP 开发了 TemplateLite、EaseTempalte 和 DzTemplate 模版引擎插件。而且对于 自己熟悉的模版引擎来说,非常容易扩展类似的插件。然后在项目配置文件里面配置使用何种模板引擎 就可以了。27 ThinkPHP2.1 常见问题&开发技巧1.52如何输出其他模块的操作模板?系统提供的 display 方法支持调用不同位置的模板文件,包括其他模块的操作,例如下面的方 法可以调用 Member 模块的 read 操作模板: $this-&display('Member:read');1.53模板文件开头的&taglib name=’html’ /&是什么意思?这表示当前模板文件要加载 html 标签库,这样在模板文件里面就能使用类似 &html:list & &html:link & 之类的标签了,内置的模板引擎是基于标签库和 XML 解析的,所以必须 要引入相应的标签库才能进行标签解析,因为系统默认会加载 cx 标签库,所以 &volist & &eq & 这样的标签是不需要自己加载标签库的。Cx 标签库之外的都需要在模板文件的开 头用&tagLib 标签首先引入标签库。1.54编辑器无法识别 XML 标签,模板标签的定界符可以定制吗?内置的模板引擎默认采用的是 XML 标签作为标签的定界符,但是可以修改的,下面是系统默认 的配置,包括普通模板引擎和标签库的标签的起始和结束标记: 'TMPL_L_DELIM'=&'{', 'TMPL_R_DELIM'=&'}', 'TAGLIB_BEGIN'=&'&', // 模板引擎普通标签开始标记 // 模板引擎普通标签结束标记 // 标签库标签开始标记28 ThinkPHP2.1 常见问题&开发技巧'TAGLIB_END'=&'&',// 标签库标签结束标记需要注意的两种类型的标记不要设置为相同的,以免引起混淆而无法正常解析。1.55如何获取模板输出的内容?Action 类的 display 方法是用于渲染模板文件并输出,可以使用 fetch 方法渲染模板文件但不 是直接输出,而是返回内容。1.56模板文件里面经常使用的__URL__和 __APP__有什么用?如果使用了内置模板引擎的话,可以在模板文件里面使用一些已经定义好的特殊字符串,系统 在输出模板的时候会自动替换成相关的系统常量,这些可替换的字符串包括: ../Public //项目公共目录 __PUBLIC__ __ROOT__ __TMPL__ //网站公共目录 //网站根目录 //当前模板目录__APP__ //当前项目地址 __URL__ //当前模块地址 __ACTION__ //当前操作地址__SELF__ //当前页面地址29 ThinkPHP2.1 常见问题&开发技巧1.57如何在模板文件中直接输出系统变量和常量?系统变量,必须以$Think.打头,如 {$Think.server.script_name } //取得$_SERVER 变量 {$Think.session.session_id } // 获取$_SESSION 变量 {$Think.get.pageNumber } //获取$_GET 变量 {$Think.cookie.name } //获取$_COOKIE 变量输出系统常量 {$Think.const.__FILE__ } {$Think.const.MODULE_NAME }1.58ThinkPHP 调试起来方便吗?ThinkPHP 支持调试模式,在调试模式下面系统默认开启了日志记录、关闭了字段缓存、关闭 了模板缓存,记录了执行过程中的 SQL 语句和运行时间,并且开启了页面运行时间显示和 Trace 功能。 要开启调整模式,在项目配置中添加如下设置: 'APP_DEBUG' =& true 在程序的数据调试输出方面,我们提供了非常有用的方法:30 ThinkPHP2.1 常见问题&开发技巧dump($var) //在浏览器输出方便查看的变量信息 halt($msg) //输出信息,并中止执行1.59ThinkPHP 的页面 Trace 是什么作用?页面 Trace 功能是 ThinkPHP 用于调试当前页面状态信息、错误记录和 SQL 记录,是一个非常 有帮助的调试手段。而且开发人员可以定制需要显示的信息。1.60怎么查看上次执行的查询语句是什么?如果你开启了调试模式,可以在日志文件里面查看最近执行过的 sql 语句和执行时间。如果没 有开启,也可以使用调试方法来查看,下面的代码可以查看上次执行的 SQL 语句: $User = D('User'); // 执行查询 $User-&where('status&1')-&order('create_time desc')-&limit(10)-&findAll(); // 查看上次执行的 SQL 语句 echo $User-&getLastSql();31 ThinkPHP2.1 常见问题&开发技巧1.61经常看到的 D 方法和 C 方法是什么意思?ThinkPHP 为一些常用的操作定义了快捷方法,这些方法具有单字母的方法名,具有比较容易 记忆的特点,D 方法和 C 方法是其中用的比较多的。 D 方法用于快速创建模型对象的实例,并且单例化,例如: $User = D(&User&); 等效为 $User = new UserModel();C 方法用于快速获取和修改配置参数,例如: 设置名称为 USER_AUTH_ON 的配置参数 C('USER_AUTH_ON',true); 获取 USER_AUTH_ON 的变量值 C('USER_AUTH_ON'); 除了 D 和 C 方法外,系统还提供了 A、S 和 L 方法,具体可以查阅手册。1.62ThinkPHP 是否可以支持 Jquery 和其他的 JS 框架?ThinkPHP 框架本身不会干涉客户端的任何东西,包括 JS,唯一一个的区别是因为框架采用了 单一入口和默认的 PATHINFO 模式,改变了传统的 URL 路径,也就是说所有所有的调用路径应该都是 基于入口文件的 URL 位置来。32 ThinkPHP2.1 常见问题&开发技巧1.63如何采用子目录的方式缓存数据?系统默认的文件缓存是在同一个目录下面的,也就是 Runtime/Temp 目录,但是可以配置启用 子目录缓存: 'DATA_CACHE_SUBDIR'=&True 这样,系统会自动生成文件的哈希子目录来存放数据缓存,防止出现同一个目录下面缓存数据过多 的情况。1.64使用 ThinkPHP 的过程中为什么总是容易发生乱码?ThinkPHP 默认使用的是 UTF8 编码,确保你的编码设置正确并且和你的配置保持一致。1.65使用 ThinkPHP 开发一定要使用 UTF8 编码吗?ThinkPHP 使用 UTF8 编码只是参考目前的网站开发标准而采取的一种默认配置和建议,你完 全可以通过配置更改你需要使用的编码格式,包括数据库编码、模板文件编码和输出编码,而且一旦配 置系统还可以实现编码的自动转换。默认的配置下,以上三者的编码都是 UTF8 编码,对于相同的编码 格式系统不会进行额外的编码转换过程。33 ThinkPHP2.1 常见问题&开发技巧1.66如何用 S 方法删除缓存?利用 S(‘name’,NULL); 可以删除标识为 name 的缓存。1.67如何设置永久缓存某个数据?设置缓存有效期为-1 就可以永久缓存某个数据,例如 S(‘name’,$data,-1);1.68ThinkPHP 是怎么进行安全过滤的?系统提供了多个层面的安全过滤机制,最大程度的保证了数据的安全。 首先,数据库底层驱动类已经对查询进行了安全过滤; 在模型里面可以定义自动验证来对提交的数据进行校验; 利用自动完成机制对非法篡改的数据进行重新写入; 利用字段自动过滤功能对写入数据库的字段进行过滤; 利用 Action 的 getParam 方法对提交的数据进行更严格的用户自定义过滤。 利用基于 RBAC 的权限验证机制防范没有授权的操作 ThinkPHP 提供了各种手段,但不代表系统会自动帮你完成各种安全过滤,完全要根据项目的要求进 行合理的配置。34 ThinkPHP2.1 常见问题&开发技巧1.69什么是 MVC?MVC 是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用 MVC 应用程序 被分成三个核心部件:模型(M)、视图(V)、控制器(C),它们各自处理自己的任务。 视图 :视图是用户看到并与之交互的界面。对老式的 Web 应用程序来说,视图就是由 HTML 元素 组成的界面,在新式的 Web 应用程序中,HTML 依旧在视图中扮演着重要的角色,但一些新的技术已层 出不穷,它们包括 Adobe Flash 和象 XHTML,XML/XSL,WML 等一些标识语言和 Web services。如 何处理应用程序的界面变得越来越有挑战性。MVC 一个大的好处是它能为你的应用程序处理很多不同的 视图。在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来 讲,它只是作为一种输出数据并允许用户操纵的方式。 模型 :模型表示企业数据和业务规则。在 MVC 的三个部件中,模型拥有最多的处理任务。例如它 可能用象 EJBs 和 ColdFusion Components 这样的构件对象来处理数据库。被模型返回的数据是中立的, 就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次 就可以被多个视图重用,所以减少了代码的重复性。 控制器 :控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击 Web 页面中的 超链接和发送 HTML 表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪 个模型构件去处理请求,然后确定用哪个视图来显示模型处理返回的数据。 现在我们总结 MVC 的处理过程,首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理, 然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据, 并通过表示层呈现给用户。35 ThinkPHP2.1 常见问题&开发技巧1.70如何快速架构项目?首先将下载的 ThinkPHP 放在你的网站根目录下面,接着在网站根目录里面建立一个 index.php(不一定非要是 index.php 也可以是别的),文件写入如下代码 define('THINK_PATH','./ThinkPHP/'); define('APP_NAME','MyApp'); define('APP_PATH','./MyApp'); require(THINK_PATH.&/ThinkPHP.php&); App::run(); 其中“.”代表 index.php 文件所在的路径,然后浏览器输入 http://localhost/index.php 运行后就会发现系统自动在网站根目录下面创建了 MyApp 文件夹,这只是一个例子,大家可以根 据自己的需要对路径设置稍作修改就可以了。1.71为何无法更新数据表字段?用 ThinkPHP 的 save 方法更新数据,但是无法完成字段更新。这个时候可以删除字段缓存文件 后重新测试,字段缓存文件位于 Runtime/Data/_fields/目录。36 ThinkPHP2.1 常见问题&开发技巧1.72用 M 方法或者 D 方法实例化模型有什么区别?简单说使用 M 方法的话,是不需要定义对应的模型类的(即使有定义也不会读取),通常这样 的模型仅能调用一些系统基础模型类 Model 类里面的一些方法。而使用 D 方法实例化模型的话,必须有 对应的模型类文件,可以调用一些模型自定义的方法或者属性,另外在 Mode 对应文件里面有自动验证 或者函数之类的业务逻辑也必需用 D。 再打个比方说 M 是刚安装好的操作系统,只有系统自带的应用 还没有自己安装的应用(所以只能调 用内置的 Model 提供的属性和方法)D 是已经安装了很多的第三方的应用程序 使用起来更丰富一些(可 以调用模型类自己定义的属性和方法)但是很明显,安装了很多的第三方应用后系统性能降低了,执行 变慢了,但是功能显然强大了。1.73修改了 Common 函数文件,怎么运行的时候没有任何变化?修改了 Common 函数文件后,需要删除 Runtime 下面的缓存文件~app.php 才能生效,如果 需要经常修改 Common 函数文件,请开启调试模式,系统就不会自动生成项目编译缓存文件。1.74如何添加自己的函数库?放在项目目录下面的 Common/common.php 系统会自动加载该函数,但是修改 common.php 之后记得一定要删除下项目编译缓存文件~app.php。37 ThinkPHP2.1 常见问题&开发技巧1.75如何更新同字段名的多条记录?用 $_post[‘字段名’] 将得到一个数组,然后循环更新,参照代码 $M = M(&Config&); for($i = 0;$i & count($_POST[&id&]); $i++) { $data[&id&] = $_POST[&id&][$i]; $data[&body&] = $_POST[&body&][$i]; $M-&save($data); }1.76为何 RBAC 改了路径就没有权限了?RBAC::AccessDecision() 这个方法是权限判断的,默认是读取当前项目名称,项目名称又是 你自己初始开设的项目目录,当提交 RBAC 时候,在数据表中有录入的初始的项目名称,现在又改项目 目录名称了,查询对比不符,所以无权限。 参照代码:RBAC::AccessDecision('现在的项目录名称'); 或者在数据表 Node 里找到你之前的项 目目录名称,改成现在的项目名称。38 ThinkPHP2.1 常见问题&开发技巧1.77为什么$this-&error() 和$this-&success()跳转同一个模板文件?Thinkphp 的默认配置错误和成功是一个模板,可以在配置里面添加 'TMPL_ACTION_ERROR' =& 'Public:error' // 默认错误跳转对应的模板文件 'TMPL_ACTION_SUCCESS' =& 'Public:success' //默认成功跳转对应的模板文件1.78怎么输出原生查询的结果?如果使用了 ThinkPHP 的原生查询 Query 方法的话,返回的结果和 select 方法一样,是返回数 据集而不是数据,因为是一个二维数组,所以在输出的时候应该使用 volist 模板标签输出。1.79如何获得上一步插入记录的 id?ThinkPHP 模型类的 add()方法返回值就是上一步插入数据的 id 或者调用模型类的 getLastInsID 方法39 ThinkPHP2.1 常见问题&开发技巧2开发技巧以下是我们整理的在使用 ThinkPHP 开发过程中的一些实用技巧,如果没有特殊的说明,均在 2.*版本中有效。2.1 创建数据对象后的更改在使用 create 方法之后,我们仍然可以对创建的数据对象进行任何操作。 例如: $User = M('User'); $User-&create(); //创建 User 数据对象 $User-&status = 1; // 设置默认的用户状态 $User-&create_time = time(); // 设置用户的创建时间 $User-&add(); // 把用户对象写入数据库 模型的 create 方法是用于创建数据对象,因为是创建到内存,因此在写入数据库之前可以随意添加 或者更改。很多开发者为了需要自己设置字段,而放弃 create 方法,其实大可不必。 上面的处理方式有两个好处: 1、动态的更改字段可以避免在模型里面定义定义自动完成 或者直接使用 M 方法实例化模型而减少 开销 2、可以解决在某些特殊的情况下难以统一定义自动完成的情况40 ThinkPHP2.1 常见问题&开发技巧2.2 定义实际的数据表名称当你的数据表命名毫无规范可言(对于已有的数据库没有什么是不可能的~)没有统一规范的表前缀, 表名大小写无规律,面对如此严峻的事实,你感到头脑发晕,但是千万不忘了 TP 的模型有一个终极武器, 为每个模型定义实际的数据表名称。只需要在模型类里面添加 protected $trueTableName = '你的真实表名'; 定义 trueTableName 属性后 会忽略当前的数据表前缀和 tableName 定义。而无论当前的模型名 称是否和表名一致~2.3 定义实际的数据库名称如果需要操作的某些数据表还存在跨库的情况,并且不是配置文件中定义的当前数据库,则可以在 模型类中加上数据库的定义: protected $dbName = '数据库名称'; 注意,要确保当前数据库用户有跨库操作的权限。2.4 获取个别字段的值在连贯操作中 我们可以使用 field 方法来定义要返回的字段 $list = $User-&field('id,name')-&select(); dump($list); 会输出: array(3) {41 ThinkPHP2.1 常见问题&开发技巧[0] =& array(2) { [&id&] =& string(1) &1& [&name&] =& string(5) &admin& } [1] =& array(2) { [&id&] =& string(1) &2& [&name&] =& string(8) &thinkphp& } [2] =& array(2) { [&id&] =& string(1) &3& [&name&] =& string(4) &test& } 如果不想返回数据集,而只是想返回一个以 id 为索引的包含 name 的数组,那么可以简单使用 $data = $User-&getField('id,name'); dump($data); 会输出: array(3) { [1] =& string(5) &admin& [2] =& string(8) &thinkphp&42 ThinkPHP2.1 常见问题&开发技巧[3] =& string(4) &test& }注意 $User-&getField('name')和 $User-&getField('id,name'); 的返回值类型是完全不同的,前者只是返回 name 的值,并且始终只有一个。 输出的结果为: string(5) &admin& 如果你只想取一个字段的值,但是希望返回数组的话,可以使用 $User-&getField('id,id');总结:模型类的 getField 方法是一个双关方法2.5 设置字段别名连贯操作的 field 方法可以用于设置查询的返回字段,根据数据库的查询优化建议,无论要返回多少 字段,都尽量显示指定要查询的字段名。 今天我们要说的是如何在查询的时候指定字段别名,以及如何返回一些特殊的动态字段。 $User-&field('id,nickname as name,status')-&select();43 ThinkPHP2.1 常见问题&开发技巧这里把 nickname 设置成 name 别名后,查询结果里面就存在 name 字段而不存在 nickname 字段 了。 利用这个技巧,我们可以实现一些实际并不存在的动态字段,例如,返回 $User-&join('think_card card on think_user.id=card.user_id')-&field('id,count(card.id) as card_count')-&select();2.6 字段的表达式更新在使用 TP 的 save 方法或者 add 方法的时候,通常我们只能对数据对象赋简单的值,但是如果希望 在字段写入的时候使用表达式的话,该如何处理呢?例如,我们希望完成下面这样的操作: update think_user SET status=1,score= score+10 where name='thinkphp' 我们可以使用 $User-&status =1; $User-&score = array('exp','score+10'); $User-&where('name=&thinkphp&')-&save(); 这个表达式的例子比较简单,其实可以使用更加复杂的,包括使用 mysql 的函数等等。 一旦使用 exp 的话,系统就会认为后面不再是一个值,而是一个表达式了。同样在 add 方法也可以 使用字段表达式2.7 字段的动态查询ThinkPHP 提供了数据的动态查询方法,可以简化你的查询代码,例如:44 ThinkPHP2.1 常见问题&开发技巧$User-&where('name=&ThinkPHP&')-&find(); 可以简化为: $User-&getByName('ThinkPHP');$User-&where('email=&&')-&find(); 可以简化为: $User-&getByEmail('');getBy**** 方法里面的**** 会转换成小写的字段名,如果字段不存在,就会出错。 如果你的字段名是 user_id ,那么查询方法应该写成: $User-&getByUserId(5); UserId 会被解析成为数据库的 user_id 字段,这点需要注意,以免引起不必要的麻烦。 目前尚不支持,对多个字段的动态查询。2.8 针对主键的几个特殊用法在 TP 的 CURD 中 有几个特别为主键的查询和删除方便而考虑的几个特殊用法: 1、find: $User-&find(3); 表示查询主键为 3 的用户记录 也可以支持字符串主键45 ThinkPHP2.1 常见问题&开发技巧$User-&find('U4321'); 需要注意的是,该方式的查询条件会覆盖 where 方法中定义的条件 $User-&where('id=5')-&find(3); id=5 的查询条件将无效2、select: $User-&select('1,2,5'); 表示查询主键范围在 1,2,5 之内的用户数据 如果是字符串主键,需要注意 $User-&select(&'U1','U2','U5'&); 每个主键要用引号3、delete: $User-&delete(3); 表示删除主键为 3 的用户数据 $User-&delete('3,5'); 表示删除主键为 3 和 5 的用户数据 如果是字符串主键,需要写成 $User-&delete(&'U3','U5'&);46 ThinkPHP2.1 常见问题&开发技巧2.9 获取当前 Action 的名称由于某些原因,我们经常会在项目中定义一个公共的 Action,例如 CommonAction,然后在里面 添加一些公共的操作方法,在这些公共方法里面,我们常常需要获取当前的 Action 名称,我们可以调用 Action 的 getActionName 方法,使用如下: $name = $this-&getActionName(); 这样就能确保正确获取继承的 Action 类的 Action 名称。注意必须在 Action 类里面使用 早期 1.5 版本里面可以使用 $name = $this-& 来完成同样的功能,但是由于和模板赋值机制有冲突,因此 2.0 版本开始就取消了,这点需要注意。2.10获取当前 Model 的名称由于某些原因,我们经常会给项目定义一个公共的 Model,例如 CommonModel,然后在里面添 加一些公共的查询方法,在这些公共方法里面,我们常常需要获取当前的 Model 名称,我们可以调用 Model 的 getModelName 方法,使用如下: $name = $this-&getModelName(); 这样就能确保正确获取继承的 Model 类的 Model 名称。注意必须在 Model 类里面使用 早期 1.5 版本里面可以使用 $name = $this-& 来完成同样的功能,但是由于和 ActiveRecord 特性的获取数据对象的属性有冲突,因此 2.0 版本开 始就取消了,这点需要注意。47 ThinkPHP2.1 常见问题&开发技巧2.11原生 SQL 和数据表替换TP 的模型可以支持原生 SQL 操作,提供了 query 和 execute 两个方法,为什么原生 SQL 还要区分 两个方法呢,原因有两个: 1、返回类型不同 query 用于查询,返回的是数据集,和 select 或者 findall 一样,所以可以直接在模板里面使用 volist 标签输出 query 的查询结果 execute 用于写操作,返回的是状态或者影响的记录数 2、读写统计需要 为了便于统计当前的数据读写次数,把数据库的读和写操作分开(对应的就是 query 和 execute)使用原生 SQL 很简单,我们甚至不需要实例化任何的模型,例如: $Model = new Model(); // 实例化一个空模型 下面的方法是等效的 $Model = D(); 或者 $Model = M(); // 下面执行原生 SQL 操作 $Model-&query('select * from think_user where status=1'); $Model-&execute('update think_user set status=1 where id=1'); 如果你实例化了某个模型,仍然可以执行原生 SQL 操作,不受影响,例如: $User = D('User');48 ThinkPHP2.1 常见问题&开发技巧$User-&query('select * from think_user where status=1'); $User-&execute('update think_user set status=1 where id=1'); 在这种情况下面,我们可以简化 SQL 语句的写法,例如: $User-&query('select * from __TABLE__ where status=1'); $User-&execute('update __TABLE__ set status=1 where id=1'); 系统会自动把__TABLE__替换成当前模型对应的数据表名称,实际的数据表由模型决定。通常来说,我们都是使用原生 SQL 操作实现一些 ORM 和 CURD 比较难实现的操作,另外,如果 SQL 不复杂的话 原生 SQL 的效率和连贯操作的效率差别是微乎其微的,TP 本身的 ORM 实现也是相当 高效的。2.12快速切换到其他的数据库从 2.1 版本开始,不用继承高级模型类也可以在操作过程中切换不同的数据库了。2.1 版本的模型 用很简洁的方式实现了数据库的切换,用法很简单, 只需要调用 Model 类的 db 方法,用法: Model-&db(&数据库编号&,&数据库配置信息&); 数据库编号用数字格式,对于已经调用过的数据库连接,是不需要再传入数据库连接信息的,系统 会自动记录。 数据库配置信息采用 DSN 字符串方式设置,格式采用: 数据库类型://用户名:密码@数据库地址:数据库端口/数据库名称49 ThinkPHP2.1 常见问题&开发技巧Db 方法调用后返回当前的模型实例,不需要和高级模型中的切换数据库方法一样,需要先添加然后 再切换过去,直接可以继续进行其他操作,所以该方法在查询的过程中动态切换,例如: $this-&db(1, &mysql://root:123456@localhost:3306/test&)-&query(&查询 SQL&); 该方法添加了一个编号为 1 的数据库连接,并自动切换到当前的数据库连接。 当第二次切换到相同的数据库的时候,就不需要传入数据库连接信息了,可以直接使用: $this-&db(1)-&query(&查询 SQL&); 如果需要切换到默认的数据库连接,只需要调用: $this-&db(0);2.13利用别名快速加载类库添加别名定义使用 alias_import 方法 alias_import(array( 'myClass' 'myUtil' =& LIB_ATH.'/Common/myClass.class.php', =& LIB_ATH.'/Common/myUtil.class.php',// ... 定义更多的别名 ) ); 我们可以在项目的公共文件 common.php 的最后添加这段代码。 定义之后,我们可以直接使用 myClass 和 myUtil 类,例如:50 ThinkPHP2.1 常见问题&开发技巧$class = new myClass(); 这个时候系统会自动根据 myClass 定义的类库路径 自动加载到 myClass 类。2.14自动加载类库自动加载类库,是指在无需通过 require 和 TP 内置的 import 方法加载类库文件即可在需要的时候 自动加载,自动加载机制可以让代码更简洁,并且利用得当的话,效率反而比手动加载有提升。 自动加载机制有四个方式: 1、列入系统的核心编译类别的类库都无需加载即可使用 2、定义了别名的类库会自动加载 3、当前项目的模型和 Action 类都会自动加载 4、自动搜索路径下面的类库可以自动加载 自动加载的类库文件命名必须是以 class.php 为后缀的。如何定义别名之前已经提过了,如果你有很多的类库 不想一一定义别名的话,可以使用定义自动搜 索路径的方法,定义 APP_AUTOLOAD_PATH 配置参数,该参数惯例配置的值是 'Think.Util.',也就是说所有位于基类库 Think/Util/目录下面的类库都可以自动加载,但是我们还可 以增加更多的搜索路径,例如: 'APP_AUTOLOAD_PATH'=&'Think.Util.,@.Common.', 这样定义后,所有位于系统基类库 Think/Util/和项目应用类库 Lib/Common/ 下面的类库也会自动 加载。51 ThinkPHP2.1 常见问题&开发技巧2.15文件哈希子目录缓存ThinkPHP 内置的缓存可以支持包括 File、Db、Apc、Memcache、Shmop、Sqlite、Xcache、 Apachenote、Eaccelerator 在内的缓存方式。系统的惯例配置默认使用文件方式缓存,也就是 File 方 式。 文件方式默认的缓存目录位于项目的 Runtime/Temp/ 目录下面,并且不再区分子目录。如果你的 缓存数据比较多,就可以启用哈希子目录缓存,只需要简单配置下面的参数: 'DATA_CACHE_SUBDIR'=&true, // 开启子目录缓存 'DATA_PATH_LEVEL'=&1 // 子目录层次 默认为 1 哈希子目录缓存仅对 File 方式的缓存有效。设置以后,缓存文件会自动生成以缓存文件名的哈希规则为目录名的多层子目录。从而避免在同一 目录下面缓存太多文件带来的性能损失。设置以后,缓存代码不用改变,还是使用: S($name,$data); // 缓存数据 S($name); // 获取缓存数据S($name,NULL); // 删除缓存数据2.16使用正则表达式进行自动验证TP 的自动验证机制是为了进行表单数据验证,验证可以支持 function、callback、confirm、equal、 unique 和 regex,这里要讲的是使用正则表达式进行验证。52 ThinkPHP2.1 常见问题&开发技巧一般我们见的比较多的是设置规则为 require、email 之类的,其实这些本身也是属于正则表达式验 证方式,只是系统内置定义了一些常用的正则表达式而已。这些内置的正则表达式的定义可以参考 model 类的 regex 方法,内置支持的正则定义包括: require 字段必须、email 邮箱、url URL 地址、currency 货币、number 数字、zip 邮编、 integer 整数、double 浮点数、english 英文字母,但是并不局限于这些正则规则的,我们完全可以直 接在验证规则里面使用正则表达式进行定义,这样我们可以凭借强大的正则表达式来进行表单字段验证, 例如: array('name','/^[a-z]\w{3,}$/i','名字不符合要求!'); array('password','/^[a-z]\w{6,30}$/i','密码不符合要求!'); array('account','/^[A-Za-z]+$/','账号必须使用英文!');附上一些表单验证中比较常用的正则表达式写法: 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 匹配双字节字符(包括汉字在内):[^\x00-\xff] 匹配 Email 地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 匹配网址 URL 的正则表达式:[a-zA-z]+://[^\s]* 匹配帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z09_]{4,15}$ 匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}53 ThinkPHP2.1 常见问题&开发技巧匹配中国邮政编码:[1-9]\d{5}(?!\d) 匹配 ip 地址:\d+\.\d+\.\d+\.\d+ 匹配特定数字: ^[1-9]\d*$ ^-[1-9]\d*$ ^-?[1-9]\d*$ ^[1-9]\d*|0$ ^-[1-9]\d*|0$ //匹配正整数 //匹配负整数 //匹配整数 //匹配非负整数(正整数 + 0) //匹配非正整数(负整数 + 0) //匹配正浮点数 //匹配负浮点数 //匹配浮点数 //匹配非负浮点数(正浮点数 + 0) //匹配非正浮点数(负浮点数 + 0)^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ 匹配特定字符串: ^[A-Za-z]+$ ^[A-Z]+$ ^[a-z]+$//匹配由 26 个英文字母组成的字符串 //匹配由 26 个英文字母的大写组成的字符串 //匹配由 26 个英文字母的小写组成的字符串 //匹配由数字和 26 个英文字母组成的字符串^[A-Za-z0-9]+$ ^\w+$//匹配由数字、26 个英}

我要回帖

更多关于 thinkphp 小程序源码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信