thinkphp5的简单学习

196 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第十五天,点击查看活动详情

安装

可以使用composer进行安装

composer create-project topthink/think=5.0.* tp5  --prefer-dist

也可以直接去官网下载压缩包,解压到自己的www文件夹下面

环境

tp5需要php版本为5.4以上,这里是5.5.9 安装完毕后访问public文件夹,看到下面的页面则安装完毕 image.png

目录和文件

目录使用小写+下划线; 类库、函数文件统一以.php为后缀; 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致; 类文件采用驼峰法命名(首字母大写),其它文件采用小写+下划线命名; 类名和类文件名保持一致,统一采用驼峰法命名(首字母大写);

函数和类、属性命名

类的命名采用驼峰法(首字母大写),例如 User、UserType,默认不需要添加后缀,例如UserController应该直接命名为User; 函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 get_client_ip; 方法的命名使用驼峰法(首字母小写),例如 getUserName; 属性的命名使用驼峰法(首字母小写),例如 tableName、instance; 以双下划线“__”打头的函数或方法作为魔术方法,例如 __call 和 __autoload;

常量和配置

常量以大写字母和下划线命名,例如 APP_PATH和 THINK_PATH; 配置参数以小写字母和下划线命名,例如 url_route_on 和url_convert; 来源: www.kancloud.cn/manual/thin…

目录结构

一般可以见名知意,主要看下主目录 application ---------应用目录 index ----------模块目录 controller -----------控制器目录 extend ---------扩展类库 public ---------对外访问目录 runtime ---------应用运行时目录(缓存) thinkphp ---------框架系统目录(核心文件) vendor ---------第三方类库目录(composer等) think ----------入口文件

url访问

http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/参数/值…

这里我这里只能通过普通方式url参数访问 http://localhost:82/public/index.php?s=/index/Demo/test/ image.png 这里需要设置下config.php里面的内容,将true设置为false image.png 就可以使用/模块/控制器/方法进行访问 image.png

访问外部文件的方法

命令空间

首先需要使用use来引用类,vscode这里很舒服的就是输入类名,就会有联想,回车后就会自动use类所在的命名空间 image.png

<?php

namespace app\index\controller;

use think\Config;

class Demo
{
    public function getConfig()
    {
        $config = Config::get("paginate");
        var_dump($config);
    }
}

image.png

助手函数

tp5提供了助手函数,引用的话可以直接输入名字而不需要再use命名空间

$config = config("paginate");

是因为在thinkphp->helper.php里面有这个函数 image.png

配置作用域

// 导入my_config.php中的配置参数,并纳入user作用域 Config::load('my_config.php','','user'); 可以用助手函数range()设置当前文件的作用域

Config::range('test');

配置环境变量

tp的环境变量配置是在根目录的.env文件下,可以有两种方式设置。

[mvc]
moduleKey = m
controllerKey = c
methodKey = a

database_username =  root
database_password =  123456

获取环境变量使用Env::get('xxx');

路由

三种模式,普通模式、强制模式、混合模式

指定路由

application\route.php 可以在指定路由的时候指定请求类型,不指定的话默认为任何请求类型

use think\Route;
Route::rule("xxx/id","index/xxx/xx","POST");

指定路由请求类型

//指定请求类型为get

Route::any('new/:id','News/read',['method'=>'get']);

//定义get请求方式,并设定url后缀为html时生效

Route::get('new/:id','News/read',['ext'=>'html']);

控制器

跳转

使用loader里面的input函数和Jump里面的success,需要先继承Controller类后才可以使用jump里面的函数

use think\Controller;

class Demo extends Controller
public function abc()
    {
        $id = input("param.id", 0, "intval");
        if ($id == 1) {
            $this->success("输出成功", "index/Demo/hello");
        }
    }

image.png image.png 跳转成功后后缀会变成.html,这是因为tp的伪静态设置,application/config

    // URL伪静态后缀
    'url_html_suffix'        => 'html',

也可以使用助手函数里面的redirect跳转到外网 $this->redirect("www.csdn.net/");

空操作

如果方法不存在,可以使用_empty来进行跳转,配合助手函数进行跳转

public function _empty($name)
    {
        $this->error("不存在该方法", "index/Demo/hello");
    }

请求

获取url

public function getUrl()
    {
        print Request::instance()->url();
    }

获取模块/控制器/操作名称

public function getUrl()
    {
        //获取模块/控制器/操作名称
        $request = Request::instance();
        print "当前模块名称是" . $request->module() . "</br>";
        print "当前控制器名称是" . $request->controller() . "</br>";
        print "当前操作名称是" . $request->action() . "</br>";
    }

image.png 能够获取到的参数

        $server['REQUEST_URI']  = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
        $server['QUERY_STRING'] = $queryString;
        $options['cookie']      = $cookie;
        $options['param']       = $params;
        $options['file']        = $files;
        $options['server']      = $server;
        $options['url']         = $server['REQUEST_URI'];
        $options['baseUrl']     = $info['path'];
        $options['pathinfo']    = '/' == $info['path'] ? '/' : ltrim($info['path'], '/');
        $options['method']      = $server['REQUEST_METHOD'];
        $options['domain']      = $server['HTTP_HOST'];
        $options['content']     = $content;
        self::$instance         = new self($options);
        return self::$instance;

可以使用input或者has判断是否存在

public function getUrl()
    {
        //获取模块/控制器/操作名称
        $request = Request::instance();
        var_dump($request->has("id", "get"));
        var_dump(input("id", "get"));

        //获取param值
        var_dump($request->param("name"));
    }

image.png 仅获取部分变量使用only,排除使用except,除了逗号分割,也可以使用数组格式,如['id','name']

var_dump($request->only("id,name"));

image.png

请求类型伪装

在post里面设定_method的值为put,那么其实他真正的请求类型为post

    // 表单请求类型伪装变量
    'var_method'             => '_method', 
<!DOCTYPE html>
<html>
    <body>
        <form method="post" action="">
            <input type="text" name="name" value="Hello">
            <input type="hidden" name="_method" value="PUT">
            <input type="submit" value="提交">
        </form>
    </body>

</html>

获取header头的内容

var_dump($request->header());

image.png

数据库

数据库的连接首先需要配置参数,application -> database.php 输入自己数据库的用户名密码等 image.png 测试是否连接成功, library -> think ->Db.php

 public function mysql()
    {
        $value = Db::query("select * from `manage` where id = 1");
        var_dump($value);
    }

image.png

插入多条数据

单条数据使用insert函数,多条数据可以使用insertall函数

public function insert()
    {
        $data = [            ['name' => 'bob', 'sex' => 'm', 'score' => '80'],
            ['name' => 'cc', 'sex' => 'w', 'score' => '90']
        ];
        db('per')->insertAll($data);
    }

更新数据

public function update()
    {
        $res = Db::table("per")->where('id', 1)->update(["name" => "coco"]);
        if ($res) {
            print "更新数据成功";
        } else {
            print "更新数据失败";
        }
    }

更新数据之前:

image.png 更新之后:

image.png

多条数据查询

whereOr

public function sel()
    {
        $res = Db::table("per")->where('name', 'like', 'cc')->whereOr('id', '2')->find();
        var_dump($res);
    }

数据为空则抛出错误

public function sel()
    {
        Db::table("per")->where('name', 'like', 'c')->failException()->select();
    }
}

或者使用更简单的,selectOrFail()

Db::table("per")->where('name', 'like', 'c')->selectOrFail();

事务操作

自动事务

public function au()
    {
        Db::transaction(function () {
            Db::table("per")->where('id', 2)->update(["name" => "cc"]);
        });
    }

事务回滚内容可以参考往期文章:panaceasec.cn/archives/my…

模型

逻辑和数据库的操作的相关方法都在模型中 定义一个模型类,这里指定了数据库和数据表

<?php

namespace app\index\model;

use think\Model;

class Demo extends Model
{
    // 设置当前模型对应的完整数据表名称
    protected $table = 'per';

    // 设置当前模型的数据库连接
    protected $connection = [
        // 数据库类型
        'type'        => 'mysql',
        // 服务器地址
        'hostname'    => '127.0.0.1',
        // 数据库名
        'database'    => 'test',
        // 数据库用户名
        'username'    => 'root',
        // 数据库密码
        'password'    => 'zhuangyan',
        // 数据库编码默认采用utf8
        'charset'     => 'utf8'
    ];
}

在controller/demo调用model 因为该文件的类为Demo类,文件开头use的命名空间 为Demo,所以会报错,那么就可以给它起个别名

use app\index\model\Demo as DemoModel;
    public function model()
    {
        $res = DemoModel::get(2);
        print "<pre>";
        var_dump($res);
        print "</pre>";
    }
}

image.png 修改name值

public function model()
    {
        $res = DemoModel::get(2);
        $res->name = "alice";
        $res->save();
        print "<pre>";
        var_dump($res);
        print "</pre>";
    }

image.png 插入数据,可以逐个插入,也可以以数组的方式插入

        $res = DemoModel::get(2);
        $res->id = "1";
        $res->name = "bob";
        $res->sex = "m";
        $res->score = "67";
        $res->save();

        $res->data(
            [
                "id" => "4",
                "name" => "alen",
                "sex" => "m",
                "score" => "99"
            ]
        );
        $res->save();

image.png 更新数据时可以使用allowField(true)函数:允许字段为空,所以即使插入非字段的值也不会报错 设置只读字段,那么在更新的时候就只会更新其他字段

    protected $readonly = ["name", "score"];

更新前: image.png 更新后: image.png ** 删除和软删除 ** 在实际项目中,对数据频繁使用删除操作会导致性能问题,软删除的作用就是把数据加上删除标记,而不是真正的删除,同时也便于需要的时候进行数据的恢复。 软删除需要引用softdelete,

use traits\model\SoftDelete;

        Demo::destroy(1);
        // 真实删除
        Demo::destroy(1,true);
        $res = Demo::get(1);
        // 软删除
        $res->delete();
        // 真实删除
        $res->delete(true);

关联自动写入:together()

$blog = new Blog;
$blog->name = 'thinkphp';
$blog->title = 'ThinkPHP5关联实例';
$content = new Content;
$content->data = '实例内容';
$blog->content = $content;
$blog->together('content')->save();

一对多关联使用hasMany(),field()确定范围

视图

新建index/view/Demo/test.html

<html>

<body>
   ssssss
</body>

</html>

在demo.php里面定义方法

    public function test()
    {
        return $this->fetch();
    }

image.png 引用不同的值,可以使用fetch也可以使用assign函数

    public function test()
    {
        return $this->fetch("", [
            "name" => "pa"
        ]);
    }
        $this->assign("name", "hello");
        return $this->fetch("test");

使用view()助手函数实现渲染和赋值操作

        $this->assign("name", "hello");
        return View("test");

test.html:

<html>
<body>
   {$name}.{$sex}.{$email}.</br>
   {$Request.get.id}
    </body>
</html>

使用share()进行全局任何地方实现静态赋值,获取url中id的值可以直接在html中定义$Request.get.id

        \think\View::share(["name" => "bob", "sex" => "m", "email" => "123@qq.com"]);

image.png 模板引擎设置 config.php -> template() 默认目录是在view目录下,可以设置view_path来更改位置

'template'               => [
        // 模板引擎类型 支持 php think 支持扩展
        'type'         => 'Think',
        // 模板路径
        'view_path'    => '',
        // 模板后缀
        'view_suffix'  => 'html',
        // 模板文件名分隔符
        'view_depr'    => DS,
        // 模板引擎普通标签开始标记
        'tpl_begin'    => '{',
        // 模板引擎普通标签结束标记
        'tpl_end'      => '}',
        // 标签库标签开始标记
        'taglib_begin' => '{',
        // 标签库标签结束标记
        'taglib_end'   => '}',
    ],

指定模板输出

return $this->fetch('edit'); 

也可以调用其他控制器下的模板

return $this->fetch('member/read');

日志

日志文件存放在runtime/log下

    public function logtest()
    {
        Log::write("test.log".json_encode(input("param.")));
        return 1;
    }

调试

trace调试

config.php中,默认为false

开启trace调试后可以看到自己的SQL语句 image.png

变量调试

tp可以使用var_dump或者print输出语句进行输出调试 halt相当于执行var_dump后再执行exit()

性能调试

调用debug

        Debug::remark("start");
        $value = Db::table("per")->where('id', 4)->find();
        Debug::remark("end");
        var_dump(Debug::getRangeTime("start", "end") . "s");

查看这条数据库查询时间用了多少时间 image.png 或者可以直接使用助手函数debug,例如debug(“start”)

sql调试

两种办法,一是上面的开启trace调试,二是开启database.php里面的调试模式,那么就可以在日志里面看到 image.png