最近自学了ThinkPHP,这里做一个学习过程记录,希望以后记忆模糊的时候可以翻看。
一)ThinkPHP安装
1)官网已经不再提供软件包下载,采用composer和git的方式下载和更新;
2)Windows安装方式
下载安装composer之后,先通过命令行配置composer:
composer config -g repo.packagist composer https://packagist.phpcomposer.com
如果下载缓慢或上述地址产生障碍,可以使用国内阿里云镜像地址:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
3)开启服务器环境
wamp或者PHPstudy,浏览器地址栏输入loacalhost进行测试,看是否可以登录本地服务器。
4)进到wamp或者PHPstudy的www目录下,安装ThinkPHP对应版本:
composer create-project topthink/think=5.1.* tp5.1test
说明:后缀tp5.1test指的是目录名。
5)安装完think框架之后,进行打开测试,浏览器地址栏输入:
http://localhost/tp5.1test/public/
如果安装成功,则可以成功打开“ThinkPHP V5.1欢迎页面”。
6)如需更新项目版本,则可以进入项目根目录,然后通过以下命令进行更新:
composer update topthink/framework
二)URL解析
ThinkPHP的URL访问规则如下:
http://serverName/index.php/模块名/控制器名(类名)/操作名/参数/值...
说明:serverName指的是“localhost/tp5.1test/public”,这一整段都是serverName,后续部署网站时就对应云服务器或服务器的IP。
截图如下所示:
举例:
http://localhost/tp5.1test/public/index.php/test/abc/hello/name/jimson
截图如下:
另外,还有另一种访问方式:
http://localhost/tp5.1test/public/index.php?s=test/abc/hello/name/jimson
而且,我们可以通过配置Apache的配置文件httpd.conf,将它里面的mod_rewrite.so这一行前面的#好去掉,然后重启环境,即可省略一些URL访问更加简洁:public/index/abc/hello/name/jimson
三)模块设计
ThinkPHP框架的默认访问模块是index,可以通过config目录下的app.php进行设置,截图如下:
如果application目录下的模块目录只有一个(一般指小项目),则可以通过配置app.php的app_multi_molule选项设置成false,截图如下:
并且可以通过在index.php里的:
Container::get('app')->bind('test')->run()->send();
这种方式绑定单一的模块。
而且如果该单一的模块下只有一个控制器,则可以继续追加:
Container::get('app')->bind('test/abc')->run()->send();
但是注意,上面这种绑定和追加的方式会使其他模块无法访问,只适用于单模块形式。
空模块
我们还可以通过配置app.php的其他选项来控制模块的行为属性,比如empty_module可以控制空模块:
'empty_module' => '404'
一般可以设置一个404的页面,使空模块指向它。
但是注意,空模块生效的前提是多模块开启和没有bind模块。
另外,如果我只有一个模块index,则模块的目录可以去掉,然后配置app.php的app_multi_molule选项设置成false,只需要controller目录即可,而命名空间也就去掉了模块名:
namespace app\controller;
截图如下:
四)环境变量
ThinkPHP提供了一个类库Env来获取环境变量,可以用来获取当前项目的各种目录,如应用目录、框架目录、路由目录等等,截图如下:
获取方式:
Env::get('app_path');
说明:get是一个类方法(静态方法)。
五)控制器定义
继承控制器可以更方便使用功能,但不是必须,继承的方式是:
use think\Controller;
class Index extends Controller
打开调试模式,截图如下:
更改根命名空间,需要在项目根目录下新建.env文件,配置以下键值对参数:
app_namespace=application
说明:将项目根命名空间配置为application。
渲染输出的三种方式
1)return
直接将结果return回去即可:
return "这是结果";
2)json输出(比如输出数组)
举例如下:
$data = array('a'=>1,'b'=>2,'c'=>3);
return json($data);
3)模板输出
创建步骤如下两个截图:
模板初始化
可以通过重写Controller类的initialize方法进行模板的初始化:
use think\Controller;
protected function initialize()
{
parent::initialize();
//初始化内容
//......
}
六)控制器操作
1、前置操作
可以更加灵活的初始化,方式是通过定义一个属性来实现:
protected $beforeActionList = [
'first',
//one方法执行不调用second前置
'second' => ['except' => 'one'],
//third前置只能通过调用one和two方法触发
'third' => ['only' => 'one,two'],
];
protected function first()
{
echo 'first<br />';
}
protected function second()
{
echo 'second<br />';
}
protected function third()
{
echo 'third<br />';
}
public function one()
{
echo "one";
}
public function two()
{
echo "two";
}
2、重定向
ThinkPHP的Controller类提供了两个跳转的方法,success(msg,url)和error(msg),用于实现跳转重定向:
public function index()
{
if($this->flag)
{
$this->success('成功!','../');
} else {
$this->error('失败!');
}
}
其实上面跳转的页面是:
thinkphp/tpl/dispatch_jump.tpl
成功和失败都是跳转上面这个页面,当然我们也可以进行修改,修改的位置截图如下:
3、空方法和空控制器
空方法可以通过定义特定的方法进行拦截:
public function _empty($name)
{
return "此方法不存在:".$name;
}
空控制器也可以进行拦截,通过定义Error控制器的形式,截图如下:
七)数据库与模型
Navicat给root设置密码,截图如下:
新建模型和模型访问对应数据,步骤截图如下:
八)查询数据
查询的常见方法有下面的这些:
Db::name();
Db::table();
find();
findOrFail();
findOrEmpty();
select();
selectOrFail();
value('username');
getLastSql();
column('username','id'); //查询指定列数据,按id排序
order('id','desc'); //将结果倒叙排序显示,一般接于where语句之后
注意:除了find和select方法是结果查询之外,其余方法查询结果均为数据库对象,它们可以一直使用链式查询操作,直到遇到find和select方法为止。
多次新建查询对象会对资源造成浪费,所以一般进行这更加安全的操作,截图如下:
九)数据库增删改操作
常见方法如下:
insert();
delete();
update();
十)查询表达式
十一)模型定义
模型定义名称必须和数据库的数据表命名对应,比如你的数据表是tp_user,则符合规范的模型定义名称是User。
1)手动修改主键
之后删除数据时则需要指定修改的主键才能删除,而不是创建时的主键,截图如下:
说明:指定主键之后,上面destroy只能根据指定的主键进行删除。
2)指定数据表
因为定义模型时数据表名称(比如tp_user)和模型名称(比如User)是对应关系,但是我们可以手动指定数据表,截图如下:
3)模型初始化
截图如下:
另外注意,模型操作和数据库操作有区别:
数据库操作需要指定表,而模型操作不需要;
数据库操作返回的列表是一个二维数组,而模型操作返回的是一个对象数组。
截图如下:
十二)模型添加和删除
模型往数据库添加数据和删除数据举例如下。
添加方式的截图:
删除方式的截图:
十三)模型修改和查询
1、更新(修改)
1)通过定义update,然后通过get方法获取主键的方式进行更新,截图如下:
注意:如果是通过save方法进行更新,数据本身没有变化,则不更新,如果想强制更新,则可以使用force方法:
$user->force()->save();
2)通过where和find方法进行更新,截图如下:
3)通过raw方法进行更新,截图如下:
注意:inc指price升序。
4)通过save([],[])两个数组参数的形式进行更新,第一个参数指需要更新的数据,第二个参数指查询条件,截图如下:
5)使用savaAll方法进行批量修改,发方法返回被修改的数据集合,截图如下:
注意:该方法第一个参数是固定的,为id,只能通过主键id进行批量修改。
6)最后一种方式是通过静态方法where结合update方法,或者直接通过静态方法update进行更新,截图如下:
这里发现,模型的新增和修改都是通过save方法进行,所以操作过多容易造成混乱,可以通过isUpdate方法进行标识,false则为新增,true则为更新,截图如下:
2、查询
1)get方法,截图如下:
2)where和find方法,截图如下:
注意:get和find方法查询数据,如果不存在则返回null。
3)通过getOrFail和findOrEmpty方法查询。
注意:第一个方法获取数据不存在时抛出异常,第二个则返回空模型。
4)获取单独的字段,可以通过使用“->”符号进行获取,但是模型内部不推荐使用$this->username这种方式,而是通过getAttr方法的方式,如下两个截图:
5)其他的查询方式,截图如下:
十四)模型获取器和修改器
获取器:获取到进行过滤操作(比如输出对应中文,变成大写等等)。
1、获取器
1)方式一
我们可以通过定义getFieldAttr()方法的方式(Field指数据库数据表中对应字段的名字),获取到数据库数据表中某个字段所有的值(也就是定义数据表时的某个Field,比如status),但是字段本身的类型可能有很多类型,比如是数值或字符串等等,我们这时就会有其他的需求,比如根据不同数值输出对应的中文,那这个功能就叫做获取器。
截图如下两个:
注意:这个Status就是指Field了。
另外可以定义虚拟字段对所有字段任意进行过滤,截图如下:
被过滤的字段我们也可以通过特定的方法输出其原始值,截图如下:
2)方式二
我们还可以通过WithAttr方法在控制器中直接实现动态获取器,截图如下:
注意:模型获取器(也就是第一种方式)优先级高于动态获取器。
2、修改器
我们可以通过定义setFieldAttr()方法的方式定义修改器,截图如下:
注意:新增和修改都会调用触发修改器,但是注意,修改器只对模型方法有效,数据库操作方法无效,不触发,比如insert这些方法。
十五)模型搜索器和数据集
1、搜索器
搜索器与获取器这些类似,是对查询表达式的封装,截图如下:
2、数据集
数据集指的是通过all和select方法查询返回的数据集对象,和数组操作方法一样,循环遍历、删除元素等等。
截图如下:
最近新开了一个微信订阅号“飞策科技”,欢迎大家的关注,关注之后阅读更加方便。