从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 相关文章推荐
phpMyAdmin出现无法载入 mcrypt 扩展,请检查PHP配置的解决方法
Mar 26 PHP
关于PHP实现异步操作的研究
Feb 03 PHP
php判断数组中是否存在指定键(key)的方法
Mar 17 PHP
了解PHP的返回引用和局部静态变量
Jun 04 PHP
PHP程序员不应该忽略的3点
Oct 09 PHP
PHP实现基于文本的摩斯电码生成器
Jan 11 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
Mar 25 PHP
Yii2中添加全局函数的方法分析
May 04 PHP
PHPMailer使用QQ邮箱实现邮件发送功能
Aug 18 PHP
在Laravel 中实现是否关注的示例
Oct 22 PHP
PHP 数组操作详解【遍历、指针、函数等】
May 13 PHP
php并发加锁问题分析与设计代码实例讲解
Feb 26 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
PHP session常见问题集锦及解决办法总结
2007/03/18 PHP
php 根据url自动生成缩略图并处理高并发问题
2014/01/23 PHP
php建立Ftp连接的方法
2015/03/07 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
没有document.getElementByName方法
2013/08/19 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
通过js简单实现将一个文本内容转译成加密文本
2013/10/22 Javascript
Javascript 数组排序详解
2014/10/22 Javascript
javascript遇到html5的一些表单属性
2015/07/05 Javascript
javascript封装简单实现方法
2015/08/11 Javascript
浅谈javascript的Touch事件
2015/09/27 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
2016/04/06 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
2017/02/28 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
JS按钮闪烁功能的实现代码
2017/07/21 Javascript
简单易扩展可控性强的Jquery转盘抽奖程序
2019/03/16 jQuery
Python编码爬坑指南(必看)
2016/06/10 Python
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
python生成特定分布数的实例
2019/12/05 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
利用Python发送邮件或发带附件的邮件
2020/11/12 Python
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
C语言面试题
2013/05/19 面试题
下列程序在32位linux或unix中的结果是什么
2015/01/26 面试题
法律专业个人实习自我鉴定
2013/09/23 职场文书
法学专业个人求职信
2013/09/26 职场文书
单位承诺书格式
2014/05/21 职场文书
公司合并协议书范本
2014/09/30 职场文书
网络营销实训总结
2015/08/03 职场文书
班主任经验交流心得体会
2015/11/02 职场文书
2016年教师节感言
2015/12/09 职场文书
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python