【ThinkPHP5】 学习笔记-转载
project 应用部署目录 ├─application 应用目录(可设置) │ ├─common 公共模块目录(可更改),不肯直接通过浏览器访问,详细办法请通过继承或者其他。 │ ├─index 模块目录(可更改) │ │ ├─config.php 模块配置文件 │ │ ├─common.php 模块函数文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录 │ │ ├─view 视图目录 │ │ └─ ... 更多类库目录 │ ├─command.php 命令行工具配置文件 │ ├─common.php 应用公共(函数)文件 │ ├─config.php 应用(公共)配置文件 │ ├─database.php 数据库配置文件,可设置本项目的数据库情况。 │ ├─tags.php 应用行为扩展定义文件,相当于钩子。对框架进行拓展。改变框架执行流程。 │ └─route.php 路由配置文件,配置这个选项可以美化URL ├─extend 扩展类库目录(可定义),下载第三方的库使用的。不包含composer ├─public WEB 部署目录(对外访问目录) │ ├─static 静态资源存放目录(css,js,image) │ ├─index.php 应用入口文件 │ ├─router.php 快速测试文件,可以用来在没安装apache的时候启动框架的web服务器。 │ └─.htaccess 用于 apache 的重写 ├─runtime 应用的运行时目录(可写,可设置)。日志、缓存和编译文件等。 ├─vendor 第三方类库目录(Composer),通过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 命令行入口文件
未提及到的个别目录:
public\robots:给搜索引擎使用的,可以设置哪些不给搜索引擎爬取等。比如前台希望能,而后台不希望给搜索引擎看到。配置这个文件即可。
\thinkphp\tpl\default_index.tpl:自动生成的控制器模板文件
\thinkphp\tpl\dispatch_jump.tpl:网站跳转成功或者失败而出现的文件。
\thinkphp\tpl\page_trace.tpl:调试时候显示的模板文件。
\thinkphp\tpl\think_exception.tpl:异常时候的模板文件
application\extend\:放第三方的类库的,如exmail,支付函数等等。
public\static\:拿来放第三方的静态资源的,比如jquery,编辑器等等。
application\admin\extra\:放extend里面的第三方类库对应的配置文件的。
————关于common模块的使用:由于common模块比较特殊,是不能直接访问的。但是common是可以给其他模块调用的。所以采用继承的方式进行使用。
以下为例,在index/Index/user方法使用common\Index控制下的a方法:
<?php
namespace app\index\controller;
use app\common\controller\Index as commonIndex; //声明使用common\Index控制器,并重命名为commonIndex,这时候其实是个类了。
class Index extends commonIndex //采用继承的方式
{
public function user (){
return $this->a(); //请注意:这里是$this,代表的就是extend的commonIndex这个类。
}
}
————以上只是一种方法,可以不用继承,而在用的时候先进行实例化,再进行->方法操作即可。效果相同。
TP框架的惯例配置:在ThinkPHP的convention.php里面。
应用配置:
开发中不允许改变框架的任何文件,否则后期升级框架就会非常的麻烦。一旦升级就很多东西都没了。那么如何自定义配置呢?在application中配置config.php即可。
请注意:TP5.0.10的调试模式的开启和关闭是在config.php里面的。而且默认是关闭的。卧槽!

加载模板采用return $this->fetch();如下
<?php
namespace app\admin\controller;
use think\controller;
class Index extends Controller
{
public function index(){
return $this->fetch();
}
}
——请注意:这时候的fetch()是默认加载跟方法同名的index.html模板的,如果你想加载相同控制器下的login模板,直接写return $this->fetch('login');如果你想跨模块调用,可以直接一级级往上改变,比如return $this->fetch('index/index');
关于数据库的设置:

模型层:用来操作数据库的,所以,一个模型文件通常对应一个数据表名字,并且与数据表的名字一致。比如:
这是我的数据表的名字:

这是我的操作的模型层的文件名:(前缀blog_在database.php文件里面设置过了。)

获取input进来的数据:通过input('post.')来获取所有。.后面加参数就是获取某个
个function login()
{
//测试数据库连接
//$data = db('admin')->where('admin_id',2)->find();
//dump($data);
if (request()->isPost()) {
//halt($_POST);
//将请求交给模型层进行处理。
//$res = (new Admin())->login(input('post.'));
dump(input('post.'));
}
}
get传参的演示:
前端:
<a href="{:url('admin/index/useredit',['admin_id'=>$user.admin_id,])}" class="edit btn btn-primary">编辑</a>
控制器:
$admin_id=input('admin_id',0);
dump($admin_id);
ajax异步发数据以及请求:
后台:
if (request()->isPost()){
//通过ajax接收来自前端的admin_id,才能确定要操作的是哪一个。
if(input('admin_id')){
return input('admin_id');
}
前端:
$('.edit').click(function () {
adminId = $(this).attr('idx');
$.ajax({
type: "POST",
url: "{:url('admin/index/useredit')}",
data: {
admin_id:adminId,
},
dataType: "json",
timeout:3000,
success: function(data){
if(data){
alert(data);
}
}
});
})
将数据添加/插入数据库:
$data = [
'admin_username' => input('post.admin_username'),
'admin_password' => md5(input('post.admin_password')),
];
db('admin')->insert($data);
验证器:
这是5.0推荐的验证方式,为具体的验证场景或者数据表定义好验证器类,直接调用验证类的check方法即可完成验证,下面是一个例子:
我们定义一个\app\index\validate\User验证器类用于User的验证。
前端验证输入:
原先我是用JQ写的,如下:
var adminusername = $('#adminusername').val();
var adminpassword = $('#adminpassword').val();
var captcha = $('#captcha').val();
if(adminusername == '' || adminpassword == ''){
layer.alert('账号或密码不能为空!');
return false;
}
if(captcha == ''){
layer.alert('请输入验证码!');
return false;
}
以下为实例,登录的例子代码:
目录结构如下:

前端登录界面的login.html
<form action="login" method="post">
<h2 class="text-center text-primary">后台管理</h2>
<div class="form-group">
<label for="adminusername">账号:</label>
<input required type="text" id="adminusername" name="admin_username" class="form-control" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="adminpassword">密码:</label>
<input required type="password" id="adminpassword" name="admin_password" class="form-control" placeholder="请输入密码">
</div>
<div class="form-group">
<label for="captcha">验证码</label>
<input required type="text" id="captcha" name="captcha" class="form-control" placeholder="请输入验证码">
</div>
<div><img src="{:captcha_src()}" alt="captcha" onclick="this.src = this.src + '?' + Math.random()"/></div>
<div>
<input type="submit" class="btn btn-success form-control" value="登录">
</div>
<div class="text-center text-info">Copyright Linfeng © 2017 - 2027</div>
</form>
控制器Login.php的代码:
<?php
namespace app\admin\controller;
use think\controller;
use app\common\model\Admin;
class Login extends Controller
{
function login()
{
//测试数据库连接
//$data = db('admin')->where('admin_id',2)->find();
//dump($data);
if (request()->isPost()) {
//将请求交给模型层进行处理,我们在模型层设置了验证以及返回的错误信息了。
$res = (new Admin())->login(input('post.'));
if ($res['valid']){
//说明登录成功
$this->success($res['msg'],'admin/index/index');exit;
}else{
//说明登录失败
$this->error($res['msg']);exit;
}
}
//加载模板
return $this->fetch();
}
}
模型层common/Admin.php
<?php
namespace app\common\model;
use think\Loader;
use think\Model;
class Admin extends Model
{
protected $pk = 'admin_id';//主键
protected $table = 'blog_admin';//请注意,必须得写完整的表名
/*
* 登录
* */
public function login($data)
{
//1、执行验证(账号密码是否输入、验证码是否输入和正确),放在了validate/Admin.php
$validate = Loader::validate('Admin');
if (!$validate->check($data)){
//如果验证不成功,返回错误信息给控制器。
return ['valid' => '0','msg' => $validate->getError()];
}
//2、比对用户名和密码是否正确
$userinfo = $this->where('admin_username',$data['admin_username'])->where('admin_password',md5($data['admin_password']))->find();
if (!$userinfo){
//说明在数据库未匹配到该用户
return [
'valid' => '0',
'msg' => '用户名或者密码错误',
];
}
//3、正确,将用户信息存入session中。
session('admin.admin_id',$userinfo['admin_id']);
session('admin.admin_username',$userinfo['admin_username']);
return [
'valid' => '1',
'msg' => '登录成功!',
];
}
}
验证模块validate\Admin.php
<?php
namespace app\admin\validate;
use think\Validate;
class Admin extends Validate
{
protected $rule = [
/*以下注释是因为前端做了处理,不然总是因为未输入而跳转,麻烦。*/
/*'admin_username' => 'require',
'admin_password' => 'require',
'captcha' => 'require|captcha',*/
'captcha' => 'require|captcha',
];
protected $message = [
/*'admin_username.require' => '请输入用户名',
'admin_password.require' => '请输入密码',
'captcha.require' => '请输入验证码',*/
'captcha.captcha' => '验证码不正确',
];
}
公共层Common.php
<?php
namespace app\admin\controller;
use think\controller;
use think\Request;
class Common extends Controller
{
public function __construct(Request $request = null)
{
parent::__construct($request);
//执行登录验证,以下相当于$_SESSION['admin']['admin_id'],这个写法在TP框架中不能用了。
if (!session('admin.admin_id')) {
$this->redirect('admin/login/login');
}
}
}
关于模型层的举例:
模型:
namespace app\index\model;
use think\Model;
class User extends Model//
{
}
控制器里面的调用方式:
namespace app\index\controller;
use app\index\model\User;//使用
class Index {
public function index()
{
$user = new User();//
}
}
请求:可以使用 think\Request,即use think\Request;
$request = Request::instance();
// 获取当前域名
echo 'domain: ' . $request->domain() . '<br/>';
// 获取当前入口文件
echo 'file: ' . $request->baseFile() . '<br/>';
// 获取当前URL地址 不含域名
echo 'url: ' . $request->url() . '<br/>';
// 获取包含域名的完整URL地址
echo 'url with domain: ' . $request->url(true) . '<br/>'; // 获取当前URL地址 不含QUERY_STRING
echo 'url without query: ' . $request->baseUrl() . '<br/>'; // 获取URL访问的ROOT地址
echo 'root:' . $request->root() . '<br/>';
// 获取URL访问的ROOT地址
echo 'root with domain: ' . $request->root(true) . '<br/>'; // 获取URL地址中的PATH_INFO信息
echo 'pathinfo: ' . $request->pathinfo() . '<br/>';
// 获取URL地址中的PATH_INFO信息 不含后缀
echo 'pathinfo: ' . $request->path() . '<br/>';
// 获取URL地址中的后缀信息
echo 'ext: ' . $request->ext() . '<br/>';
可以通过Request对象完成全局输入变量的检测,获取和安全过滤,包括$_GET/$_POST等等
验证码:
后面加随机数,是因为每次的src都不一样,就会重新请求验证码类。
<div><img src="{:captcha_src()}" alt="captcha" onclick="this.src = this.src + '?' + Math.random()"></div>
同时,验证码提供了配置项,所以可以直接加在application下的config.php文件里面。

独立验证(专门建验证文件请查看上面的验证)
任何时候,都可以使用Validate类进行独立的验证操作,例如:
$validate = new Validate([
'name' => 'require|max:25',
'email' => 'email'
]);
$data = [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
];
if (!$validate->check($data)) {
dump($validate->getError());
}
————请注意:上面的例子的$data经常会由其他地方传进来进行验证。如:
public function pass($data)
{
//1、执行验证
$validate = new Validate(
[
//'admin_id' => 'require',
'admin_password' => 'require',
'new_password' => 'require',
'confirm_password' => 'require|confirm:new_password',//本字段与new_password进行比对。
],
[
'admin_password.require' => '请输入原密码',
'new_password.require' => '请输入新密码',
'confirm_password.require' => '请输入确认密码',
'confirm_password.confirm' => '两次密码必须一致',
]
);
if (!$validate->check($data)) {
dump($validate->getError());
}
//2、原始密码是否正确
//3、修改密码
}
模板继承:
1、在view模块下建立模板base.html,并在其主区域用标签{block name='main'} {/block}包含起来。

2、在view\index\index.html继承base.html,并替换(其实是填充,之前并没有内容){block name='main'} {/block}里面的内容。

————这里我们需要特别注意:需要在base.html上写一个{block name="script"}{/block},继承界面的JS写在这个区域的。如下:上面的JS是公用的,下面的是拿来放每个界面不同的JS的。

函数:在php文件中可以直接使用,在模板中使用需要加冒号:
在模板中使用函数session:得加冒号:如下:
<strong class="font-bold">{:session('admin.admin_username')}</strong>
——上面的session('admin.admin_username')是TP框架定义的session函数。
在模板中生成地址,采用url函数,记得加冒号:
<li><a href="{:url('admin/index/userlist')}">用户列表</a></li>
form表单填写地址,直接填写模块/控制器/方法名:
<form action="{:url('admin/index/useredit')}" method="post">
————当然,action可以不写,会传到页面对应的方法上。{ }其实就是相当于在html界面的<?php ?>而已。
通过ajax传参:
$('.edit').click(function () {
adminId = $(this).attr('idx');
$.ajax({
type: "POST",
url: "{:url('admin/index/useredit')}",
data: {
admin_id: adminId,
},
dataType: "json",
timeout: 3000,
success: function () {
if (data) {
alert(1);
}
}
});
})
volist的应用:
控制器代码:
function userlist(){
$users = db('admin')->select();
//在模板中分配变量
$this->assign('users',$users);
return $this->fetch();
}
前端代码:
{volist name="users" id="vo"}
<tr>
<td>{$vo.admin_id}</td>
<td>{$vo.admin_username}</td>
<td>{$vo.admin_password}</td>
<td><a title="">删除</a></td>
</tr>
{/volist}
关于TP5中如何让左侧导航栏显示和隐藏的问题:
由于一个函数对应一个html界面,所以,我们可以在函数中直接给模板分配变量。这样就省去了采用cookie等方法记住所点击的界面了。如下:
控制器代码:
function index(){
//分配所在界面,以便于展开导航栏对应的模块。
$this->assign('active_li','index');
//加载模板
return $this->fetch();
}
请注意,我们向外分配的变量为当前的函数名(一个函数对应一个界面),然后展开导航条对应的模块,__FUNCTION__在php中是用于获取当前函数名的。上面可以改成:
function index(){
//分配所在界面的方法,以便于展开导航栏对应的模块。
$this->assign('active_li',__FUNCTION__);
//加载模板
return $this->fetch();
}
前端模板代码:
var activeLi = '{$active_li}';
$('.' + activeLi).addClass('active');


浙公网安备 33010602011771号