从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解


Posted in PHP onApril 03, 2019

本文实例讲述了从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记。分享给大家供大家参考,具体如下:

用tp3.2.3做了不少项目,但是毕竟要与时代接轨,学习一些新的框架,比如tp5

以下记录一些学习中遇到的问题及解决办法,还有tp3.2和tp5.0的一些区别,适合给用过tp3没用过tp5的童鞋做个参考。

随着学习不断更新......

+++++++++++++++++++++++分割线总是要有的+++++++++++++++++++++++

首先到tp官网下载了一个最新的ThinkPHP5.0.22完整版:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

直接扔到了服务器上,解压后目录结构如下:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

目录结构整体与tp3.2大同小异,文件夹首字母小写了,应用入口文件 在根目录下 public/index.php,官方文档对public文件夹定义为WEB部署目录(对外访问目录):

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

配置服务器域名解析的时候需要把项目根目录指向/public:

<VirtualHost *:80>
 ServerAdmin 1977629361@qq.com
 DocumentRoot /var/www/tp/public
 ServerName tp.oyhdo.com
 ServerAlias tp.oyhdo.com
 DirectoryIndex index.php index.html index.htm 
</VirtualHost>

根目录下 application/config.php 为应用(公共)配置文件,设置一些常用的配置,以下简称为“配置文件”:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

访问网址如下:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

访问tp.oyhdo.com等同于访问tp.oyhdo.com/index.php/index/Index/index(默认不区分大小写)

即默认模块index,默认控制器Index,默认操作index

配置文件修改分别为default_moduledefault_controllerdefault_action

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

如果需要强制区分url大小写,修改 url_convert false

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

配置文件中设置 app_debug true,打开应用调试模式,以便开发调试:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

【隐藏url中的index.php入口文件】

以Apache服务器为例,首先确认Apache配置文件httpd.conf中开启了mod_rewrite.so模块:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

然后把所有【AllowOverride】设为All:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

 最后修改根目录下 public/.htaccess 文件内容为:

<IfModule mod_rewrite.c>
 Options +FollowSymlinks -Multiviews
 RewriteEngine on
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
去掉index.php也可访问:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

【隐藏前台url模块名】 

把index模块作为前台,在前台新建了一个User控制器:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

<?php
namespace app\index\controller;

class User
{
 public function user()
 {
 return '这是User控制器的user操作';
 }
}

 正常需要这样访问User控制器的user操作:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

 为了前台url显示简洁一些,要去掉模块名index,然后就崩了:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

如果只有一个模块,可以在 /application/common.php 中添加:

// 绑定当前访问到index模块
define('BIND_MODULE','index');

亲测访问成功:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

但是项目通常会有前后台的区分,至少两个模块, 用上面的方法绑定index模块后,再访问其它模块就会报错:

(新建了一个admin模块作为后台)

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

<?php
namespace app\admin\controller;

class Index
{
 public function index()
 {
 return '这是后台首页';
 }
}

 从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

对于多模块的情况,可以在 /application/route.php 中绑定默认模块路由(去掉上面的单模块绑定):

use think\Route;
Route::bind('index');

前台访问成功:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

 然后在/public/下新建一个入口文件admin.php,绑定后台模块admin,来访问后台:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

<?php
// [ 应用入口文件 ]
namespace think;
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/base.php';
// 绑定当前入口文件到admin模块
Route::bind('admin');
// 关闭admin模块的路由
App::route(false);
// 执行应用
App::run()->send();

后台访问成功:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

(修改后台地址只需修改这个文件名即可)
 

【返回数据】

配置文件中默认输出类型 default_return_type 为html:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

 直接打印输出字符串、数组,没什么特殊:

public function index()
{
 $str = 'hello,world!';
 $arr = array('state'=>1,'msg'=>'success');

 //打印字符串
 echo $str;

 //打印数组
 var_dump($arr);
}

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

返回json格式数据:

public function index()
{
 $arr = array('state'=>1,'msg'=>'success');
 return json($arr);
 
 //返回其它状态码或响应头信息
 //return json($arr, 201, ['Cache-control' => 'no-cache,must-revalidate']);

 //xml格式
 //return xml($arr);
}

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

(对于只做API开发的情况,可以设置default_return_type为json,直接return $arr即可返回json格式数据)
 

【渲染模板、分配数据】

如图建立视图层,index.html作为前台首页(内容为“这是首页”):

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

tp3渲染模板直接在控制器里$this->display(),tp5并不支持。

tp5渲染模板,在控制器中继承think\Controller类,使用 return $this->fetch() 或者使用助手函数 return view()

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
 public function index()
 {
 return $this->fetch();
 //return view();
 }
}

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

tp5分配数据的方式依旧使用 $this->assign()

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
 public function index()
 {
 	$name = 'lws';
 $this->assign('name',$name);
 return $this->fetch();
 }
}

index.html页面读取数据:

{$name}

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

(修改模板引擎标签 配置文件【tpl_begin】、【tpl_end】)

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

【继承父类控制器】

写一个栗子,新建一个Base控制器作为父类控制器,Index控制器继承Base控制器

在父类控制器中初始化分配数据,子类控制器渲染模板:

Base.php:

<?php
namespace app\index\controller;
use think\Controller;
class Base extends Controller
{ 
 //初始化方法
 public function _initialize()
 {	
 	$haha = '快下班了';
 $this->assign('haha',$haha);
 }
}

Index.php:

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Base
{
 public function index()
 {
 return $this->fetch();
 }
}

index.html:

{$haha}

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

(与tp3.2相比,父类控制器不能是Public控制器) 

【配置参数】

tp3.2里面使用C方法设置、获取配置参数

tp5使用助手函数 config() 设置、获取配置参数:

//配置一个参数
config('name','lws');

//批量配置参数
config([
 'info'=>['sex'=>'nan','aihao'=>'nv']
]);

//获取一个配置参数
echo config('name');

//获取一组配置参数
dump(config('info'));

//获取一个二级配置参数
echo config('info.sex');

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

【get传参】

tp5废除了url/参数名1/参数值1/参数名2/参数值2......这样的方式传参,还是老老实实用url?参数名1=参数值1&参数名2=参数值2......这样传吧。

控制器里打印$_GET

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
 public function index()
 {
 $getdate = $_GET;
 dump($getdate);	
 }
}

 这样是不对滴:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

这样就好使:

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

【安全获取变量】 

tp3.2可以使用I方法安全获取get、post等系统输入变量

tp5中使用助手函数 input()

//获取get变量
$data1 = input('get.name');

//获取post变量
$data2 = input('post.name');

//获取当前请求变量
$data3 = input('param.name');

//获取request变量
$data4 = input('request.name');

//获取cookie变量
$data5 = input('cookie.name');

//获取session变量
$data6 = input('session.name');

//获取上传文件信息
$data7 = input('file.image');

(注意:获取的数据为数组,要加上 /a 修饰符才能获取到)

$arr = input('post.arr/a');

可以在配置文件中设置全局过滤方法:

// 默认全局过滤方法 用逗号分隔多个
'default_filter'  => 'htmlspecialchars',

【数据库操作】

tp5的数据库配置文件在根目录 /application/database.php:(也可在模块下单独配置)

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

连接数据库:tp3.2支持M方法连接数据库,tp5使用 Db类 或 助手函数db()

查询数据:依旧使用 find()select() 方法,查询一个字段使用 value() 方法代替getField()

//查询一条
$artinfo = db('article')->find();

//查询全部
$artinfo = db('article')->select();

//查询一个字段
$artinfo = db('article')->value('article_title');

添加数据:tp3.2使用add(),tp5使用 insert():返回插入条数  或  save():返回id

//添加一条数据
$data['article_title'] = 'PHP是世界上最好的语言';
$data['article_content'] = '如题';
db('article')->insert($data);
//或 db('article')->save($data);
//添加多条数据
$data = [
 ['article_title' => '标题1', 'article_content' => '内容1'],
 ['article_title' => '标题2', 'article_content' => '内容2'],
 ['article_title' => '标题3', 'article_content' => '内容3']
];
db('article')->insertAll($data);

修改数据:tp3.2使用save(),tp5使用 update()

//修改数据
$whe['article_id'] = 1;
$data['article_title'] = '修改后的标题';
db('article')->where($whe)->update($data);

删除数据:没错还是 delete()

//删除数据
$whe['article_id'] = 1;
db('article')->where($whe)->delete();

db()助手使用起来比较方便,但每次都会重新连接数据库,因此应当尽量避免多次调用,建议还是使用Db类操作数据库。

Db类操作原生SQL:

<?php
namespace app\index\controller;
use think\Db;
class Index {
 public function index() {
 // 插入记录
 $res = Db::execute('insert into lws_article (title ,content) values ("标题", "内容")');
	
 // 删除数据
 $res = Db::execute('delete from lws_article where art_id = 1 ');

 // 更新记录
 $res = Db::execute('update lws_article set title = "修改标题" where art_id = 1 ');

 // 查询数据
 $res = Db::query('select * from lws_article where art_id = 1');

 // 显示数据库列表
 $res = Db::query('show tables from blog');

 // 清空数据表
 $res = Db::execute('TRUNCATE table lws_article');
 }
}

Db类操作查询构造器:

<?php
namespace app\index\controller;
use think\Db;
class Index {
 public function index() {
	// 查询数据(数据库没有配置表前缀)
	$res = Db::table('lws_article')
	 ->where('art_id', 1)
	 ->select();

	//以下为数据库配置了表前缀	

	// 插入记录
	$res = Db::name('article')
		->insert(['title' => '标题', 'content' => '内容']);

	// 更新记录
	$res = Db::name('article')
		->where('art_id', 1)
		->update(['title' => "修改标题"]);

	// 查询数据
	$res = Db::name('article')
		->where('art_id', 1)
		->select();

	// 删除数据
	$res = Db::name('article')
		->where('art_id', 1)
		->delete();
 
 //链式操作举例
 $artlist = Db::name('article')
	 ->where('is_del', 'N')
	 ->field('id,title,content')
	 ->order('post_time', 'desc')
	 ->limit(10)
	 ->select();
 } 
}

【切换数据库】

首先在数据库配置中配置多个数据库:

// 数据库配置1
'db1' => [
	// 数据库类型
	'type' => 'mysql',
	// 服务器地址
	'hostname' => '127.0.0.1',
	// 数据库名
	'database' => 'blog1',
	// 数据库用户名
	'username' => 'root',
	// 数据库密码
	'password' => '123456',
	// 数据库连接端口
	'hostport' => '',
	// 数据库连接参数
	'params' => [],
	// 数据库编码默认采用utf8
	'charset' => 'utf8',
	// 数据库表前缀
	'prefix' => 'lws_',
],
// 数据库配置2
'db2' => [
	// 数据库类型
	'type' => 'mysql',
	// 服务器地址
	'hostname' => '127.0.0.1',
	// 数据库名
	'database' => 'blog2',
	// 数据库用户名
	'username' => 'root',
	// 数据库密码
	'password' => '',
	// 数据库连接端口
	'hostport' => '',
	// 数据库连接参数
	'params' => [],
	// 数据库编码默认采用utf8
	'charset' => 'utf8',
	// 数据库表前缀
	'prefix' => 'lws_',
],

使用connect方法切换数据库:

<?php
namespace app\index\controller;
use think\Db;
class Index {
 public function index() {
 $db1 = Db::connect('db1');
 $db2 = Db::connect('db2');
 $db1->query('select * from lws_article where art_id = 1');
 $db2->query('select * from lws_article where art_id = 2');
 }
}

【系统常量】

tp5废除了一大堆常量:

REQUEST_METHOD IS_GET 
IS_POST  IS_PUT 
IS_DELETE IS_AJAX 
__EXT__  COMMON_MODULE 
MODULE_NAME CONTROLLER_NAME 
ACTION_NAME APP_NAMESPACE 
APP_DEBUG MODULE_PATH等

需要使用的常量可以自己定义,例如IS_GET、IS_POST

我在父类的初始化方法中定义了这两个常量:

<?php
namespace app\index\controller;
use think\Controller;
class Base extends Controller
{
 public function _initialize()
 {	
 	define('IS_GET',request()->isGet());
 define('IS_POST',request()->isPost());
 }
}

然后在子类控制器中就可以使用这个常量做一些判断:

<?php
namespace app\index\controller;
class Index extends Base
{
 public function index()
 { 
 if(IS_POST){
  echo 111;
 }else{
  echo 222;
 }
 }
}

【定义路由】

例如一篇博客详情页,原来的网址为:http://oyhdo.com/home/article/detial?id=50,即home模块下的article控制器下的detial操作方法,传递参数id。

在路由配置文件 application/route.php 中添加路由规则:

return [
 'article/:id' => 'home/article/detial',
];

或者使用 Route 类,效果一样: 

use think\Route;
Route::rule('article/:id','home/article/detial');

定义路由规则之后访问http://oyhdo.com/article/50即可

从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解

 【url分隔符的修改】

修改 application/config.php 中的 pathinfo_depr :

// pathinfo分隔符
 'pathinfo_depr'  => '-',

访问网址变为:http://oyhdo.com/article-50

【跳转、重定向】

tp3里面的正确跳转:$this->success()、错误跳转:$this->error()、重定向:$this->redirect(),在tp5里面同样适用(继承\think\Controller

tp5新增 redirect() 助手函数用于重定向:

return redirect('https://www.oyhdo.com');

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP与javascript对多项选择的处理
Oct 09 PHP
使用adodb lite解决问题
Dec 31 PHP
PHP时间戳使用实例代码
Jun 07 PHP
php下检测字符串是否是utf8编码的代码
Jun 28 PHP
php中url传递中文字符,特殊危险字符的解决方法
Aug 17 PHP
三种php连接access数据库方法
Nov 11 PHP
thinkphp模板赋值与替换实例简述
Nov 24 PHP
PHP程序中使用adodb连接不同数据库的代码实例
Dec 19 PHP
php通过两层过滤获取留言内容的方法
Jul 11 PHP
php 伪造HTTP_REFERER页面URL来源的三种方法
Sep 22 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
Feb 19 PHP
thinkPHP框架实现多表查询的方法
Jun 14 PHP
PHP快速排序算法实现的原理及代码详解
Apr 03 #PHP
Laravel5.7框架安装与使用学习笔记图文详解
Apr 02 #PHP
Laravel访问出错提示:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or di解决方法
Apr 02 #PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
Apr 02 #PHP
Swoole实现异步投递task任务案例详解
Apr 02 #PHP
ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解
Apr 02 #PHP
Linux下源码包安装Swoole及基本使用操作图文详解
Apr 02 #PHP
You might like
$_GET['goods_id']+0 的使用详解
2013/06/06 PHP
Symfony数据校验方法实例分析
2015/01/26 PHP
php组合排序简单实现方法
2016/10/15 PHP
node.js中的fs.open方法使用说明
2014/12/17 Javascript
jquery实现右侧栏菜单选择操作
2016/03/04 Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
2016/09/04 Javascript
js阻止冒泡和默认事件(默认行为)详解
2016/10/20 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
Vue服务端渲染实践之Web应用首屏耗时最优化方案
2019/03/22 Javascript
js使用cookie实现记住用户名功能示例
2019/06/13 Javascript
elementui之el-tebs浏览器卡死的问题和使用报错未注册问题
2019/07/06 Javascript
详解vue-router的Import异步加载模块问题的解决方案
2020/05/13 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
openlayers4.6.5实现距离量测和面积量测
2020/09/25 Javascript
[50:34]VGJ.T vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python 中random模块的常用方法总结
2017/07/08 Python
Python解决八皇后问题示例
2018/04/22 Python
pandas.dataframe按行索引表达式选取方法
2018/10/30 Python
Selenium chrome配置代理Python版的方法
2018/11/29 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
python中多个装饰器的调用顺序详解
2019/07/16 Python
pytorch加载语音类自定义数据集的方法教程
2020/11/10 Python
python 逆向爬虫正确调用 JAR 加密逻辑
2021/01/12 Python
以实惠的价格轻松租车,免费取消:Easyrentcars
2019/07/16 全球购物
PHP笔试题
2012/02/22 面试题
电子商务专业个人的自我评价
2013/11/19 职场文书
驾驶员岗位职责
2014/01/29 职场文书
2014年消防工作实施方案
2014/02/20 职场文书
聘任书模板
2014/03/29 职场文书
画展邀请函
2015/01/31 职场文书
2015年全国“爱牙日”宣传活动总结
2015/03/23 职场文书
2015年党务公开工作总结
2015/05/19 职场文书
早会开场白台词大全
2015/06/01 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
关于PHP数组迭代器的使用方法实例
2021/11/17 PHP