thinkphp 官网教程:https://sites.thinkphp.cn/1556331
thikphp5 框架详解
- ThinkPHP5 - 从入门到实践(完整版):https://www.bilibili.com/video/BV13a4y1E7dy
- ThinkPHP5.0 框架全方位解读与实战:https://github.com/kotlindev/ThinkPHPDemo
ThinkPHP OA办公系统:https://www.bilibili.com/video/BV1LP4y1E7u5
ThinkPHP5.0 实战开发企业站:https://www.bilibili.com/video/BV1cW411w7iA
框架:框架是一堆包含了常量、方法、类 等代码的集合,它是一个半成品的应用,只包含项目开发时所使用的底层架构,并不包含业务逻辑,框架还包含了一些优秀的设计模式,如:单例模式、工厂模式、AR(Active Record)模式 等。
web 开发阶段
第一阶段:混合编程阶段 (混编)
特点:就是将 php 和 html 代码放在一个文件中。
优点:效率高,
缺点:不易维护,会造成前端人员不得不面对后端代码,后端人员不得不面对前端代码第二阶段:模板引擎
优点:将前端的输出和后端的逻辑代码分离。
缺点:效率比第一种低。第三阶段:MVC 设计阶段
优点:强制将用户的输入、逻辑、输出相互分离,在维护上简单性提高了很多。
缺点:效率比前面 2 中模式都低。
ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,目前 thinkphp 总共给出 4 个官方手册:
执行过程
动态图演示:
示例:手把手编写PHP MVC框架实例教程--FastPHP
:https://www.jianshu.com/p/0635f0c7a5b6
:https://www.kancloud.cn/special/thinkphp5_quickstart
浏览器直接访问:
注意:输出的 "index 测试" 这句话
入口文件主要作用
推荐 方法 2,即在 thinkphp 根目录下执行命令:php think build --module 模块名
方法 1:手动创建。复制 index 目录并重命名。例如 重命名为 admin,然后再修改命名空间。
方法 2:命令创建。推荐用这种方法。在 thinkphp 根目录下执行命令创建。php think build --module demo
方法3:通过入口文件创建。利用框架自带的类文件创建。在入口文件中添加 \think\Build::module('admin'); 然后浏览器访问入口文件,就会执行 php ,创建对应模块。生成成功后,一定要把入口中对应代码删除或者注释掉,要不每次访问都会生成。。。
一个典型的 Web MVC 流程:
thinkphp 默认 url 不区分大小写,如果想要区分大小写,可以在 config.php 里面配置
普通 方式:
域名/入口文件?m=index&c=index&a=index
m 代表 模块
c 代表 控制器
a 代表 控制器中方法(即动作 aciton)
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php?m=index&c=index&a=indexpathinfo 方式:
域名/入口文件/模块/控制器/方法/
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php/index/index/indexrewrite 方式:( 可以隐藏入口文件 index.php )
域名/模块/控制器/方法/
需要修改服务器配置兼容模式:
域名/入口文件?s=模块/控制器/方法/
s是可以设置的,在 config.php 中 pathinfo 变量
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php?s=/admin/index/index
http://域名(或者ip)/public/模块.php/控制器/操作/参数/值
http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php
http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php/index/index
示例:
根命名空间(类库包)
根命名空间是一个关键的概念,以上面的\think\cache\driver\File
类为例,think
就是一个根命名空间,其对应的初始命名空间目录就是系统的类库目录(thinkphp/library/think
),我们可以简单的理解一个根命名空间对应了一个类库包。
系统内置的几个根命名空间(类库包)如下:
名称 | 描述 | 类库目录 |
---|---|---|
think | 系统核心类库 | thinkphp/library/think |
traits | 系统Trait类库 | thinkphp/library/traits |
app | 应用类库 | application |
如果需要增加新的根命名空间,有两种方式 ( https://www.kancloud.cn/manual/thinkphp5/118014 ) :
EXTEND_PATH
目录(默认为extend
,可配置),就可以自动注册对应的命名空间,例如:在extend目录下面新增一个my目录,然后定义一个\my\Test类( 类文件位于extend/my/Test.php)类名 必须等于 控制器文件名
首先修改 控制器中代码,返回 一个 view,浏览器访问直接报错
可以发现找不到 index.html 文件,这时需要在对应文件夹中创建 index.html 文件。( 可以发现:一个控制器需要一个同名的 view 的子目录。多个控制器时,每个控制器会在 view 目录下有有对应同名的子目录。同时 子目录中有和 控制器方法同名的 html 文件,即 模板文件 )
单入口
访问后端或者后台等其他模块都需要统一的文件进行访问。
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php/index/index/index
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php/admin/index/index
都需要经过 index.php 文件。目前使用比较多的是单入口(框架)
多入口:
访问其他文件没有统一的入口
隐藏入口文件
示例1:http://127.0.0.1/thinkphp_5_0_24_with_extend/index/index/index
示例2:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/admin/index/index
示例1 直接是通过 "域名/模块/控制器/动作" 来访问的
示例2 是 通过 "域名/入口文件/模块/控制器/动作"
通过入口文件 index.php 可以猜测网站的使用的是 php,暴漏网站信息
可以在 .htaccess 文件中配置,从而隐藏入口文件。.htaccess必须和入口文件平级。
想要去掉 URL 地址里面的入口文件名 index.php ,需要额外配置WEB服务器的重写规则。以 Apache为例,需要在入口文件的同级添加.htaccess文件(官方默认自带了该文件),内容如下:
该目录下:TP5/public/.htaccess(TP5为框架目录)
<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>如果用的 phpstudy ,规则如下:
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
</IfModule>接下来就可以使用下面的URL地址访问了
http://tp5.com/index/index/index
http://tp5.com/index/index/hello如果你使用的 apache 版本使用上面的方式无法正常隐藏 index.php ,可以尝试使用下面的方式配置
.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>如果是Nginx环境的话,可以在 Nginx.conf 中添加:
location / { // …..省略部分代码
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
break;
}
}
请求的动作
访问 URL,验证请求的动作。
http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php/index/index/index
http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/index
http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/hello
请求参数 的 绑定
格式1:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/hello/参数1/值1/参数2/值2
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/hello/param1/100/param2/200格式2:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/hello?参数1=值1&参数2=值2
示例:http://127.0.0.1/thinkphp_5_0_24_with_extend/index.php/index/index/hello?param1=100¶m2=200
助手函数 就是 thinkphp 框架的全局函数。可以在 helper.php 中可以找到所有助手函数
thinkphp 提供的助手函数目录:
url 助手函数 示例:
下面是常用的助手函数
url 助手函数用的最多的地方就是跳转页面。最常用的是登录注册、form表单使用。
示例:<form class="register" action="{:url('index/register/doRegister')}" method="POST">
使用 url 助手函数时注意:助手函数在模板里调用,前面要加冒号 {:url('地址表达式')};
示例:\think\Controller 类的 redirect 方法可以实现页面的重定向功能。
// 重定向到 News 模块的 Category 操作。
// 跳转到 News 模块的 category 操作,重定向后会改变当前的 URL地址。
$this->redirect('News/category', ['cate_id' => 2]);
// 或者直接重定向到一个指定的外部URL地址。
// 重定向到指定的URL地址 并且使用302
示例:$this->redirect('http://thinkphp.cn/blog/2',302);
//使用redirect助手函数还可以实现更多的功能,例如可以记住当前的URL后跳转:
redirect('News/category')->remember();
//需要跳转到上次记住的URL的时候使用
redirect()->restore();
注意:跳转和重定向的URL地址不需要再使用url方法进行生成,会自动调用,请注意避免,否则会导致多次生成而出现两个重复的URL后缀
//如果要在控制器里面渲染模板,可以使用
namespace app\index\controller;
use think\View;
class Index
{
public function index()
{
$view = new View();
return $view->fetch('index');
}
}
示例:也可以使用 view 助手函数 来 渲染模板输出
namespace app\index\controller;
class Index
{
public function index()
{
return view('index');
}
}
助手函数 view
如果要获取当前的请求信息,可以使用 \think\Request 类,
$request = Request::instance();
助手函数如下:$request = request();
常用的为:
Request::instance()->param()|get()|post()|cookie()|session()|…
//默认为 param
以下代码是做验证注册是用的,可以参考一下:
public function doregister(){
if(Request::instance()->isPost()){
//接收所有的post数据
$formData = Request::instance()->post();
// dump($formData);
$userModel = new User(); //调用模型,与数据库匹配
$r_name = $formData["username"];
$r_pwd = $formData["password"];
$data = $userModel->doregister($r_name,$r_pwd);
// dump($data);
if(!$data){
$this->error("注册失败!");
}else{
$this ->success('注册成功!!',url('index/login/index'));
}
}
}
获取输入数据。input 函数默认就采用PARAM变量读取方式。
获取 GET 变量
Request::instance()->get('id'); // 获取某个get变量
Request::instance()->get('name'); // 获取get变量
Request::instance()->get(); // 获取所有的get变量(经过过滤的数组)
Request::instance()->get(false); // 获取所有的get变量(原始数组)
使用助手函数
input('get.id');
input('get.name');
input('get.');
其他获取变量方式同上,可以参考手册。
注:input("变量类型.变量名")
获取和设置配置参数。一般在分页的时候设置页码会用到:在模型中使用如下代码:
$data = $this->where($map)->order("id asc")->paginate(Config::get("page_count"),false,[
"query" => $request->get()
在config.php中代码如下:
设置分页为10页。
thinkPHP5.0开发手册PDF版 下载:https://www.kancloud.cn/manual/thinkphp5
load_trait:快速导入Traits,PHP5.5以上无需调用
/**
* 快速导入Traits PHP5.5以上无需调用
* @param string $class trait库
* @param string $ext 类库后缀
* @return boolean
*/
load_trait($class, $ext = EXT)exception:抛出异常处理
/**
* 抛出异常处理
* @param string $msg 异常消息
* @param integer $code 异常代码 默认为0
* @param string $exception 异常类
*
* @throws Exception
*/
exception($msg, $code = 0, $exception = '')debug:记录时间(微秒)和内存使用情况
/**
* 记录时间(微秒)和内存使用情况
* @param string $start 开始标签
* @param string $end 结束标签
* @param integer|string $dec 小数位 如果是m 表示统计内存占用
* @return mixed
*/
debug($start, $end = '', $dec = 6)lang:获取语言变量值
/**
* 获取语言变量值
* @param string $name 语言变量名
* @param array $vars 动态变量值
* @param string $lang 语言
* @return mixed
*/
lang($name, $vars = [], $lang = '')config:获取和设置配置参数
/**
* 获取和设置配置参数
* @param string|array $name 参数名
* @param mixed $value 参数值
* @param string $range 作用域
* @return mixed
*/
config($name = '', $value = null, $range = '')input:获取输入数据,支持默认值和过滤
/**
* 获取输入数据 支持默认值和过滤
* @param string $key 获取的变量名
* @param mixed $default 默认值
* @param string $filter 过滤方法
* @return mixed
*/
input($key = '', $default = null, $filter = null)widget:渲染输出Widget
/**
* 渲染输出Widget
* @param string $name Widget名称
* @param array $data 传入的参数
* @return mixed
*/
widget($name, $data = [])model:实例化Model
/**
* 实例化Model
* @param string $name Model名称
* @param string $layer 业务层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return \think\Model
*/
model($name = '', $layer = 'model', $appendSuffix = false)validate:实例化验证器
/**
* 实例化验证器
* @param string $name 验证器名称
* @param string $layer 业务层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return \think\Validate
*/
validate($name = '', $layer = 'validate', $appendSuffix = false)db:实例化数据库类
/**
* 实例化数据库类
* @param string $name 操作的数据表名称(不含前缀)
* @param array|string $config 数据库配置参数
* @param bool $force 是否强制重新连接
* @return \think\db\Query
*/
db($name = '', $config = [], $force = true)controller:实例化控制器,格式:[模块/]控制器
/**
* 实例化控制器 格式:[模块/]控制器
* @param string $name 资源地址
* @param string $layer 控制层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return \think\Controller
*/
controller($name, $layer = 'controller', $appendSuffix = false)action:调用模块的操作方法,参数格式:[模块/控制器/]操作
/**
* 调用模块的操作方法 参数格式 [模块/控制器/]操作
* @param string $url 调用地址
* @param string|array $vars 调用参数 支持字符串和数组
* @param string $layer 要调用的控制层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return mixed
*/
action($url, $vars = [], $layer = 'controller', $appendSuffix = false)import:导入所需的类库,同java的Import,本函数有缓存功能
/**
* 导入所需的类库 同java的Import 本函数有缓存功能
* @param string $class 类库命名空间字符串
* @param string $baseUrl 起始路径
* @param string $ext 导入的文件扩展名
* @return boolean
*/
import($class, $baseUrl = '', $ext = EXT)vendor:快速导入第三方框架类库,所有第三方框架的类库文件统一放到系统的Vendor目录下面
/**
* 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面
* @param string $class 类库
* @param string $ext 类库后缀
* @return boolean
*/
vendor($class, $ext = EXT)dump:浏览器友好的变量输出
/**
* 浏览器友好的变量输出
* @param mixed $var 变量
* @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串
* @param string $label 标签 默认为空
* @return void|string
*/
dump($var, $echo = true, $label = null)url:Url生成
/**
* Url生成
* @param string $url 路由地址
* @param string|array $vars 变量
* @param bool|string $suffix 生成的URL后缀
* @param bool|string $domain 域名
* @return string
*/
url($url = '', $vars = '', $suffix = true, $domain = false)session:Session管理
/**
* Session管理
* @param string|array $name session名称,如果为数组表示进行session设置
* @param mixed $value session值
* @param string $prefix 前缀
* @return mixed
*/
session($name, $value = '', $prefix = null)cookie:Cookie管理
/**
* Cookie管理
* @param string|array $name cookie名称,如果为数组表示进行cookie设置
* @param mixed $value cookie值
* @param mixed $option 参数
* @return mixed
*/
cookie($name, $value = '', $option = null)cache:缓存管理
/**
* 缓存管理
* @param mixed $name 缓存名称,如果为数组表示进行缓存设置
* @param mixed $value 缓存值
* @param mixed $options 缓存参数
* @param string $tag 缓存标签
* @return mixed
*/
cache($name, $value = '', $options = null, $tag = null)trace:记录日志信息
/**
* 记录日志信息
* @param mixed $log log信息 支持字符串和数组
* @param string $level 日志级别
* @return void|array
*/
trace($log = '[think]', $level = 'log')request:获取当前Request对象实例
/**
* 获取当前Request对象实例
* @return Request
*/
request()response:创建普通Response对象实例
/**
* 创建普通 Response 对象实例
* @param mixed $data 输出数据
* @param int|string $code 状态码
* @param array $header 头信息
* @param string $type
* @return Response
*/
response($data = [], $code = 200, $header = [], $type = 'html')view:渲染模板输出
/**
* 渲染模板输出
* @param string $template 模板文件
* @param array $vars 模板变量
* @param array $replace 模板替换
* @param integer $code 状态码
* @return \think\response\View
*/
view($template = '', $vars = [], $replace = [], $code = 200)json:获取Json对象实例
/**
* 获取\think\response\Json对象实例
* @param mixed $data 返回的数据
* @param integer $code 状态码
* @param array $header 头部
* @param array $options 参数
* @return \think\response\Json
*/
json($data = [], $code = 200, $header = [], $options = [])jsonp:获取Jsonp对象实例
/**
* 获取\think\response\Jsonp对象实例
* @param mixed $data 返回的数据
* @param integer $code 状态码
* @param array $header 头部
* @param array $options 参数
* @return \think\response\Jsonp
*/
jsonp($data = [], $code = 200, $header = [], $options = [])xml:获取xml对象实例
/**
* 获取\think\response\Xml对象实例
* @param mixed $data 返回的数据
* @param integer $code 状态码
* @param array $header 头部
* @param array $options 参数
* @return \think\response\Xml
*/
xml($data = [], $code = 200, $header = [], $options = [])redirect:获取Redirect对象实例
/**
* 获取\think\response\Redirect对象实例
* @param mixed $url 重定向地址 支持Url::build方法的地址
* @param array|integer $params 额外参数
* @param integer $code 状态码
* @return \think\response\Redirect
*/
redirect($url = [], $params = [], $code = 302)abort:抛出HTTP异常
/**
* 抛出HTTP异常
* @param integer|Response $code 状态码 或者 Response对象实例
* @param string $message 错误信息
* @param array $header 参数
*/
abort($code, $message = null, $header = [])halt:调试变量并且中断输出
/**
* 调试变量并且中断输出
* @param mixed $var 调试变量或者信息
*/
halt($var)token:生成表单令牌
/**
* 生成表单令牌
* @param string $name 令牌名称
* @param mixed $type 令牌生成方法
* @return string
*/
token($name = '__token__', $type = 'md5')
:https://www.php.net/manual/zh/reserved.variables.php
位置:library\think\Request.php
请求对象的作用:收集客户端的信息(form、cookie、超链接等)
方法 1:传统方式调用。先导入,然后通过 Request::instance() 实例化 Request类对象。
方法 2:继承 controller 父类。先继承,然后使用 $this->request
方法 3:自动注入请求对象。先导入,然后作为参数来使用 Request $request
方法 4:助手函数。直接在 helper.php 搜索 request,查看 request 相关说明。
使用 助手函数 request()
param()
get() 对应 $_GET
post() 对应 $_POST
session() 对应 $_SESSION
cookie() 对应 $_COOKIE
server() 对应 $_SERVER
file() 对应 $_FILES
助手函数 input
示例 ( 没有参数时,返回 空数组 ):
示例:( 请求添加参数 )
get、post 参数 提取。( 现在网站一般都是 https,所以使用 post 提取 )
tp5 框架默认开启 session
设置和读取 session
参看上面的 助手函数 input
文件位置:thinkphp\library\Response.php
默认返回值是不支持数组,但是可以在 config.php 里面修改设置 default_return_type
default_return_type 支持的类型 html/json/xml,可以修改为 json
// 使用 meta 进行刷新
echo "<meta http-equiv="Refresh" content="3" />"// 使用 script 进行刷新
echo "<script>location.href='xxx'</script>"// 使用 header 里面的 location 进行刷新
header('location:index.php')
跳转、重定向:https://www.kancloud.cn/manual/thinkphp5/118051
两种方法
重定向
更多使用方法:参看 Db.php 文件
Db 类 位置
thinkphp 中 数据库操作步骤
sql 操作又分为 两种方式:
query() ---> 查询
excute() ---> 增加、删除、修改
原生查询:增删改查语句:
// 插入数据
$result = Db::execute('insert into think_data (name,status) value("test_name",1)');
// 修改数据
$result = Db::execute('update think_data set name="test_name", status = 1 where id = 1');
// 删除数据
$result = Db::execute('delete from think_data where id = 1');
// 查询数据
$result = Db::query('select * from think_data');
插入数据
查看数据库可以发现已经插入
参数绑定
使用 Db 类 进行 链式查询
// 查询一个数据;table 方法必须指定完整的数据表名
Db::table('think_user')->where('id',1)->find();
// 查询数据集使用:
Db::table('think_user')->where('status',1)->select();
// 如果设置了数据表前缀参数的话,可以使用
Db::name('user')->where('id',1)->find();
Db::name('user')->where('status',1)->select();
使用 助手函数 db 进行 链式查询
// 助手函数;系统提供了一个 db 助手函数,可以更方便的查询:
db('user')->where('id',1)->find();
db('user')->where('status',1)->select();
insert()、update()、delete()、select() 这些方法必须放在最后
查询字段
db('user')->field('name,pwd')->select();where 条件
db('user')->where('status',1)->select();
db('user')->where('status', 'eq', '1')->select();多个 where 方法相连,表示 and 关系,需要条件同时成立
db('user')->where('status', 'eq', '1')->where('uid', 'eq', '99')->select();whereor 方法,表示 或(or) 关系
db('user')->where('status', 'eq', '1')->whereor('uid', 'eq', '99')->select();排序
db('user')->order('id', 'desc')->select();限制查询数量
db('user')->limit(5)->select();
模型中的方法 不能和 Db类中的方法 混合使用
模型的定义:https://www.kancloud.cn/manual/thinkphp5/135187
什么式模型:
注意:thinkphp 中对象和数组之间可以相互转换(arrayaccess 接口)
比如定义一个模型类 Admin,
则它对应的表名为 database.php中配置的前缀+小写的模型类型
更多方法,参看 think\Model
get() 查询一条数据
getAll() 查询多条数据save() 添加一条数据
saveAll() 添加多条数据save() 和 isUpdata() 都可以实现更新数据
destroy() 删除数据
saveAll() 保存多条数据
推荐用这种方式。。。
模型会自动对应数据表,模型类的命名规则是除去表前缀的数据表名称,采用驼峰法命名,并且首字母大写,例如:
模型名 | 约定对应数据表(假设数据库的前缀定义是 think_) |
---|---|
User | think_user |
UserType | think_user_type |
如果你的规则和上面的系统约定不符合,那么需要设置Model类的数据表名称属性,以确保能够找到对应的数据表。
视图。通俗的理解就是 显示的 HTML 。可以理解为 html 文件
视图功能由\think\View
类配合 视图驱动(模板引擎)类一起完成,目前的内置模板引擎包含PHP原生模板和Think模板引擎。
因为新版的控制器可以无需继承任何的基础类,因此在控制器中如何使用视图取决于你怎么定义控制器。
\think\Controller
类如果你的控制器继承了\think\Controller
类的话,则无需自己实例化视图类,可以直接调用控制器基础类封装的相关视图类的方法。
// 渲染模板输出
return $this->fetch('hello',['name'=>'thinkphp']);
下面的方法可以直接被调用:
方法 | 说明 |
---|---|
fetch | 渲染模板输出 |
display | 渲染内容输出 |
assign | 模板变量赋值 |
engine | 初始化模板引擎 |
如果需要调用 View类 的其它方法,可以直接使用$this->view
对象:
如果你只是需要渲染模板输出的话,可以使用系统提供的助手函数view
,可以完成相同的功能:
return view('hello',['name'=>'thinkphp']);
助手函数调用格式:view('[模板文件]'[,'模板变量(数组)'][,模板替换(数组)])
无论你是否继承think\Controller
类,助手函数都可以使用,也是最方便的一种。
模板控制怎么生成的 html,视图显示 html
不能替代教程,而是作为工具参考,学习的话新手建议先阅读官方的 《 5.0入门系列教程 》
ThinkPHP V5.0 完全开发手册:https://www.kancloud.cn/manual/thinkphp5/118003
ThinkPHP5 的环境要求如下:
严格来说,ThinkPHP5.0 无需安装过程,这里所说的安装其实就是把 ThinkPHP 框架放入WEB运行环境(前提是你的WEB运行环境已经OK),可以通过下面几种方式获取和安装ThinkPHP。
5.1 版本开始 ( 包括 5.1 ),官网不再提供下载版本,使用 Composer 或者 git 方式安装和更新。
thinkphp5 PHP 支持: 5.4.0 < php < 7.4
PHP7.4在2019年11月28日正式发布。
其中有一个变化是不再能够使用花括号来访问数组或者字符串的偏移。
下面来具体看一下。
假设我们有一个数组如下:
$arr = ['a','b','c'];
现在假设我们要访问$arr数组的第一个元素,
在7.4之前我们可以用以下两种形式:
$arr[0];
或者
$arr{0};
上面两种形式都是可以使用的,
但是从7.4开始,就不能使用第二种形式来获取数组元素了。
同样地,对于字符串的偏移量获取也不能使用大括号了。
假设有以下的字符串:$str = 'abc';
现在假设我们需要取第一个字符 "a",以前我们可以有两种形式来获取:
$str[0];
或者
$str{0};
从7.4以后,只能使用第一种形式获取字符串偏移了,第二种方法被弃用。
如果在PHP7.4以后的代码中,还是使用大括号来获取的话,那么就会抛出如下错误信息:
Array and string offset access syntax with curly braces is deprecated
这是PHP7.4的新变化,写程序的时候要注意一下了。
获取 ThinkPHP 的方式很多,官方网站(http://thinkphp.cn)提供了稳定版本或者带扩展完整版本的下载。
官网的下载版本不一定是最新版本,git 版本获取的才是保持更新的版本。
thinkPHP 5.0 拆分为多个仓库,主要包括:
https://github.com/top-think/think
https://github.com/top-think/framework
thinkphp 5.1 安装:https://www.kancloud.cn/manual/thinkphp5_1/353948
thinkphp 6.0 安装:https://www.kancloud.cn/manual/thinkphp6_0/1037481
ThinkPHP 5.1 通过 git 安装步骤:https://www.kancloud.cn/manual/thinkphp5_1/353948
ThinkPHP5.1
主要分为应用和核心两个仓库,主要包括:
- 应用项目:https://github.com/top-think/think
- 核心框架:https://github.com/top-think/framework
6.0 版本开始,必须通过 Composer 方式安装和更新,无法通过 Git 下载安装。
无论采用什么方式获取的 ThinkPHP 框架,现在只需要做最后一步来验证是否正常运行。
我本地 网站根目录
在浏览器中输入地址:http://127.0.0.1/thinkphp_5_0_24_with_extend/public/index.php
浏览器显示如图,说明已经完成 ThinkPHP5 的安装!( 其实就是放到网站的根目录下 )
ThinkPHP5遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范:
.php
为后缀;User
、UserType
,默认不需要添加后缀,例如UserController
应该直接命名为User
;get_client_ip
;getUserName
;tableName
、instance
;__call
和 __autoload
;APP_PATH
和 THINK_PATH
;url_route_on
和url_convert
;think_user
表和 user_name
字段,不建议使用驼峰和中文作为数据表字段命名。应用类库的根命名空间统一为app(不建议更改,可以设置app_namespace
配置参数更改,V5.0.8
版本开始使用APP_NAMESPACE
常量定义);
例如:app\index\controller\Index
和app\index\model\User
。
请避免使用PHP保留字(保留字列表参见 PHP: 关键词列表 - Manual )作为常量、类名和方法名,以及命名空间的命名,否则会造成系统错误。
下载最新版框架后,解压缩到web目录下面,可以看到初始的目录结构如下:
project 应用部署目录
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可更改)
│ ├─index 模块目录(可更改)
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─extend 扩展类库目录(可定义)
├─public WEB 部署目录(对外访问目录)
│ ├─static 静态资源存放目录(css,js,image)
│ ├─index.php 应用入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于 apache 的重写
├─runtime 应用的运行时目录(可写,可设置)
├─vendor 第三方类库目录(Composer)
├─thinkphp 框架系统目录
│ ├─lang 语言包目录
│ ├─library 框架核心类库目录
│ │ ├─think Think 类库包目录
│ │ └─traits 系统 Traits 目录
│ ├─tpl 系统模板目录
│ ├─.htaccess 用于 apache 的重写
│ ├─.travis.yml CI 定义文件
│ ├─base.php 基础定义文件
│ ├─composer.json composer 定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 惯例配置文件
│ ├─helper.php 助手函数文件(可选)
│ ├─LICENSE.txt 授权说明文件
│ ├─phpunit.xml 单元测试配置文件
│ ├─README.md README 文件
│ └─start.php 框架引导文件
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
如果是mac或者linux环境,请确保
runtime
目录有可写权限
5.0的部署建议是public
目录作为web目录访问内容,其它都是web目录之外,当然,你必须要修改public/index.php
中的相关路径。如果没法做到这点,请记得设置目录的访问权限或者添加目录列表的保护文件。
router.php用于php自带webserver支持,可用于快速测试
启动命令:php -S localhost:8888 router.php
5.0版本自带了一个完整的应用目录结构和默认的应用入口文件,开发人员可以在这个基础之上灵活调整。
上面的目录结构和名称是可以改变的,尤其是应用的目录结构,这取决于你的入口文件和配置参数。
由于ThinkPHP5.0的架构设计对模块的目录结构保留了很多的灵活性,尤其是对于用于存储的目录具有高度的定制化,因此上述的目录结构仅供建议参考。
ThinkPHP提供了灵活的全局配置功能,采用最有效率的PHP返回数组方式定义,支持惯例配置、公共配置、模块配置、扩展配置、场景配置、环境变量配置和动态配置。
对于有些简单的应用,你无需配置任何配置文件,而对于复杂的要求,你还可以扩展自己的独立配置文件。
系统的配置参数是通过静态变量全局存取的,存取方式简单高效。
配置功能由\think\Config
类完成。
路由功能由\think\Route
类完成。
由于ThinkPHP5.0
默认采用的URL规则是:
路由的作用是简化URL访问地址,并根据定义的路由类型做出正确的解析。
新版的路由功能做了大量的增强,包括:
ThinkPHP5.0的路由支持三种方式的URL解析规则。
5.0的路由是针对应用而不是针对模块,因此路由的设置也是针对应用下面的所有模块,如果希望不同的模块区分不同的设置(例如某些模块需要关闭路由,某些模块需要强制路由等),需要给该模块增加单独的入口文件,并作如下修改:
// 定义项目路径
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架基础文件
require __DIR__ . '/../thinkphp/base.php';
// 绑定当前入口文件到admin模块
\think\Route::bind('admin');
// 关闭admin模块的路由
\think\App::route(false);
// 执行应用
\think\App::run()->send();
V5.0.21+
版本开始,支持了路由解析缓存。
在配置文件中 设置开启
// 开启路由解析缓存
'route_check_cache' => true,
定义路由
在应用开发中,经常会遇到一些带有提示信息的跳转页面,例如操作成功或者操作错误页面,并且自动跳转到另外一个目标页面。系统的\think\Controller
类内置了两个跳转方法success
和error
,用于页面跳转提示。
使用方法很简单,举例如下:
namespace app\index\controller;
use think\Controller;
use app\index\model\User;
class Index extends Controller
{
public function index()
{
$User = new User; //实例化User对象
$result = $User->save($data);
if($result){
//设置成功后跳转页面的地址,默认的返回页面是$_SERVER['HTTP_REFERER']
$this->success('新增成功', 'User/list');
} else {
//错误页面的默认跳转页面是返回前一页,通常不需要设置
$this->error('新增失败');
}
}
}
跳转地址是可选的,success方法的默认跳转地址是$_SERVER["HTTP_REFERER"]
,error方法的默认跳转地址是javascript:history.back(-1);
。
默认的等待时间都是3秒
success
和error
方法都可以对应的模板,默认的设置是两个方法对应的模板都是:
THINK_PATH . 'tpl/dispatch_jump.tpl'
我们可以改变默认的模板:
//默认错误跳转对应的模板文件
'dispatch_error_tmpl' => APP_PATH . 'tpl/dispatch_jump.tpl',
//默认成功跳转对应的模板文件
'dispatch_success_tmpl' => APP_PATH . 'tpl/dispatch_jump.tpl',
也可以使用项目内部的模板文件
//默认错误跳转对应的模板文件
'dispatch_error_tmpl' => 'public/error',
//默认成功跳转对应的模板文件
'dispatch_success_tmpl' => 'public/success',
模板文件可以使用模板标签,并且可以使用下面的模板变量:
变量 | 含义 |
---|---|
$data | 要返回的数据 |
$msg | 页面提示信息 |
$code | 返回的code |
$wait | 跳转等待时间 单位为秒 |
$url | 跳转页面地址 |
error方法会自动判断当前请求是否属于
Ajax
请求,如果属于Ajax
请求则会自动转换为default_ajax_return
配置的格式返回信息。 success在Ajax
请求下不返回信息,需要开发者自行处理。
\think\Controller
类的redirect
方法可以实现页面的重定向功能。
redirect方法的参数用法和Url::build
方法的用法一致(参考URL生成部分),例如:
//重定向到News模块的Category操作
$this->redirect('News/category', ['cate_id' => 2]);
上面的用法是跳转到News模块的category操作,重定向后会改变当前的URL地址。
或者直接重定向到一个指定的外部URL地址,例如:
//重定向到指定的URL地址 并且使用302
$this->redirect('http://thinkphp.cn/blog/2',302);
可以在重定向的时候通过session闪存数据传值,例如
$this->redirect('News/category', ['cate_id' => 2], 302, ['data' => 'hello']);
使用redirect助手函数还可以实现更多的功能,例如可以记住当前的URL后跳转
redirect('News/category')->remember();
需要跳转到上次记住的URL的时候使用:
redirect()->restore();
跳转和重定向的URL地址不需要再使用url方法进行生成,会自动调用,请注意避免,否则会导致多次生成而出现两个重复的URL后缀
控制器定义
控制器初始化
前置操作
跳转和重定向
空操作
空控制器
多级控制器
分层控制器
Rest控制器
自动定位控制器
资源控制器
请求信息
输入变量
更改变量
请求类型
请求伪装
HTTP头信息
伪静态
方法注入
属性注入
参数绑定
依赖注入
请求缓存
新版的数据库进行了重构,主要特性包括:
新版的模型进行了重构,更加对象化操作,包括关联模型的重构,主要特性包括:
主要讲述了如何使用内置的模板引擎来定义模板文件,以及使用加载文件、模板布局和模板继承等高级功能。
ThinkPHP内置了一个基于XML的性能卓越的模板引擎,这是一个专门为ThinkPHP服务的内置模板引擎,使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签,使用了动态编译和缓存技术,而且支持自定义标签库。其特点包括:
每个模板文件在执行过程中都会生成一个编译后的缓存文件,其实就是一个可以运行的PHP文件。
内置的模板引擎支持普通标签和XML标签方式两种标签定义,分别用于不同的目的:
标签类型 | 描述 |
---|---|
普通标签 | 主要用于输出变量和做一些基本的操作 |
XML标签 | 主要完成一些逻辑判断、控制和循环输出,并且可扩展 |
这种方式的结合保证了模板引擎的简洁和强大的有效融合。
ThinkPHP5.0
的路由比较灵活,并且不需要强制定义,可以总结归纳为如下三种方式:
关闭路由,完全使用默认的PATH_INFO
方式URL:
'url_route_on' => false,
路由关闭后,不会解析任何路由规则,采用默认的PATH_INFO
模式访问URL:
http://serverName/index.php/module/controller/action/param/value/...
但仍然可以通过操作方法的参数绑定、空控制器和空操作等特性实现URL地址的简化。
可以设置url_param_type
配置参数来改变pathinfo模式下面的参数获取方式,默认是按名称成对解析,支持按照顺序解析变量,只需要更改为:
// 按照顺序解析变量
'url_param_type' => 1,
开启路由,并使用路由定义+默认PATH_INFO
方式的混合:
'url_route_on' => true,
'url_route_must'=> false,
该方式下面,只需要对需要定义路由规则的访问地址定义路由规则,其它的仍然按照第一种普通模式的PATH_INFO
模式访问URL。
开启路由,并设置必须定义路由才能访问:
'url_route_on' => true,
'url_route_must' => true,
这种方式下面必须严格给每一个访问地址定义路由规则(包括首页),否则将抛出异常。
首页的路由规则采用/
定义即可,例如下面把网站首页路由输出Hello,world!
Route::get('/',function(){
return 'Hello,world!';
});
调试模式
异常处理
抛出异常
Trace调试
变量调试
性能调试
SQL调试
远程调试
404页面
验证器
验证规则
错误信息
验证场景
控制器验证
模型验证
内置规则
静态调用
表单令牌
ThinkPHP5.0支持Console
应用,通过命令行的方式执行一些URL访问不方便或者安全性较高的操作。
我们可以在命令行下面,切换到应用根目录,然后执行php think
,会出现下面的提示信息:
>php think
Think Console version 0.1
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-V, --version Display this console version
-q, --quiet Do not output any message
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
build Build Application Dirs
clear Clear runtime file
help Displays help for a command
list Lists commands
make
make:controller Create a new resource controller class
make:model Create a new model class
optimize
optimize:autoload Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.
optimize:config Build config and common file cache.
optimize:route Build route cache.
console
命令的执行格式一般为:
>php think 指令 参数
下面介绍下系统自带的几个命令,包括:
指令 | 描述 |
---|---|
build | 自动生成目录和文件 |
help | 帮助 |
list | 指令列表 |
clear | 清除缓存指令 |
make:controller | 创建控制器文件 |
make:model | 创建模型文件 |
optimize:autoload | 生成类库映射文件 |
optimize:config | 生成配置缓存文件 |
optimize:route | 生成路由缓存文件 |
optimize:schema | 生成数据表字段缓存文件 |
更多的指令可以自己扩展。
文章浏览阅读6.3k次。日志默认info级别debug日志不会打印,但是会执行日志填充的数据例如:logger.debug("日志输出",2*10); 1. 2*10会先执行出结果,然后继续往下走2. 在ch.qos.logback.classic.Logger#filterAndLog_1方法中判断是否符合级别要求是否需要输出3.如图:..._debug中的计算是否在info级别也会跑
文章浏览阅读1.4k次。Similarly to the previous example, let us apply our calibration engine onto the data that comes with the originalcalibration toolbox of Heikkil� from the University of Oulu. Once again. do not bothe_non-planar calibration
文章浏览阅读1w次,点赞10次,收藏63次。物联网常用的网络协议:MQTT、AMQP、HTTP、CoAP、LwM2M物联网设备间沟通的语言,就是网络协议。设备间想相互交流,通信双方必须使用同一种“语言”。比如说你和中国人问好说’你好‘、日本人问好要说‘こんにちは’、和英国人问好要说‘hello’.说起网络协议,你可能马上就想到了 HTTP 协议。是的,在日常的 Web 开发中,我们总是需要跟它打交道,因为 HTTP 协议是互联网的主流网络协议。类似地,应用在互联网中的网络协议,还有收发电子邮件的 POP3 、SMTP 和 IMAP 协议,以及_lmm2m和mqtt
文章浏览阅读7.4k次,点赞4次,收藏20次。这篇博文简要记录一下使用MKL函数库计算一般矩阵的特征值与特征向量对形如对称矩阵或是埃尔米特等特殊矩阵有其对应的子程序,在这里先不涉及。有需求的可以自行查阅MKL官方文档下面给出本次示例代码:代码使用f95接口。f77借口参数太多,笔者太懒<不过懒惰是创新的原动力^_^>program testGeev use lapack95 implicit..._fortran求矩阵特征值
文章浏览阅读147次。学习内容来自:Numpy Tutorial文章目录Array SlicingArray IndexingMathematical ManipulationBroadcastingImage Processing基本的用法课程里面说的挺详细了。 特别记录一些需要关注的点。Array Slicing使用固定数字进行array寻址会导致数组降维。y = np.random.random((3,..._np.imresize
文章浏览阅读355次。题目阅览 观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。 本题要求你找到一些5位或6位的十进制数字。满足如下要求: 该数字的各个数位之和等于输入的整数。 输入格式 一个正整数 n (10<n<100), 表示要求满足的数位和。 输出格式若干行,每行包含一个满足要求的5位或6位整数。 数字按从小到大的顺序排列。 如果没有满足条件的,输出:-1样例输入144样例输出199899_c++蓝桥杯 回文数
文章浏览阅读6.2k次,点赞3次,收藏13次。需要的pom文件 <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.1.0</version>_java扫二维码进入自己制作的网页
文章浏览阅读650次。在遥感图像处理中,我们经常需要将多波段遥感影像拆分成多个单波段图像,以便进行各种分析和后续处理。本篇博客将介绍一个用Python编写的程序,该程序可以读取多波段遥感影像,将其拆分为单波段图像,并保存为单独的文件。本程序使用GDAL库来处理遥感影像数据,以及NumPy库来进行数组操作。结果如下图所示,选中的影像为输入的多波段影像,其他影像分别为拆分后的多波段影像。_一个多波段影像分解成多个单波段影像
文章浏览阅读5.1k次,点赞2次,收藏4次。0前言一直用的好好的移动硬盘突然不显示了,前段时间因为比较忙,一直没顾得上管它,趁这个假期,好好捅咕了一番,总算是弄好了,特此将解决的过程记录如下:1.问题描述 1.我的移动硬盘在其他人的电脑上能够正常显示和使用 2.其他移动硬盘在我电脑上能够正常的显示和使用 3.在我的电脑上,该移动硬盘,既不显示盘符,磁盘管理 又不显示该磁盘2.问题分析1.我的移动硬盘能够在其他人电脑上_电脑无法显示移动硬盘
文章浏览阅读1k次。Kernel initialization. Part 10.在原文的基础上添加了5.10.13部分的源码解读。End of the linux kernel initialization processThis is tenth part of the chapter about linux kernel initialization process and in the previous part we saw the initialization of the RCU and stopped o_linux 标志着kernel启动完成
文章浏览阅读5.3k次,点赞5次,收藏23次。Scala语言概述:Scala语言是一门以Java虚拟机为运行环境,支持面向对象和函数式编程的静态语言,java语言是面向对象的,所以代码写起来就会相对比较模块儿,而函数式编程语言相对比较简洁_scala安装及环境配置
文章浏览阅读2.4k次。“他来听我的演唱会,门票换了手铐一对”。最近歌神张学友变阿SIR,演唱会上频频抓到罪犯,将人脸识别技术又一次推到了大众的视线中。要说人脸识别技术的爆发,当属去年9月份苹果iPhone x的发布,不再需要指纹,只需要扫描面部就可以轻松解锁手机。任何技术一旦进入智能手机这个消费市场,尤其是被苹果这个标志性的品牌采用,就意味着它将成为一种趋势,一个智能设备的标配。在智能手机快速崛起的这几年,其密码锁..._人脸识别发展历史