markdown 语法

thinkphp学习

配置设置

优先级:动态配置>模块配置>扩展配置>应用配置>惯例配置
知识拓展以下仅供了解:
1惯例配置的作用域是全局,作用域越大,优先级越低;
2场景配置是用来切换开发场景的
3模块配置里也可细分扩展配置,很少用到,除非项目很庞大

模块设计

localhost/index/index/index报错

把. htaccess中 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

改成RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]

在其他目录使用common下的类

use app\common\controller\类名(index) as xxx;

之后2种

  1. class xx extends xxx return $this-> 方法名

  2. $xx=new xxx return $xx->方法名

惯例配置

thinkphp\convention.php

应用配置

扩展配置

config 中 改变 框架配置

  1. config.php 用来改变个别配置
  2. 新建extra目录 在其中放入 一类配置 如email,database 之后在这个配置文件中修改
  3. 拉出来的配置文件级别高与config.php 会进行 array merge

场景配置

修改app_status的值

设置"app_status" => "value",会指向value.php,所以能联系上home.php 和 office.php

value.php 要在config.php的同级目录下

模块配置

config目录下 新建与 配置模块 相同名字的 文件夹
之后便可在该文件夹中 进行 扩展配置&场景配置一类操作

动态配置

主要用于对当前控制器或某个方法里面进行动态的配置改变或动态的配置设置

  1. function __construct(){} 其中—construct类 会在同一文件中 其它方法之前运行 该代码段中不能用Config::get。

  2. 在方法中进行动态配置

    该动态配置只在该方法中生效

​ 1.config(name:' * ',value:' * ')

​ 2.Config::set

config类和助手函数config

Config 地址 thinkphp/library/think/Config.php

config 地址 thinkphp/helper.php

仔细观察 有些方法中 的值未赋 用 ' ' 跳过赋下一个值

// 导入my_config.php中的配置参数,并纳入user作用域
Config::load('my_config.php','','user'); 

// 解析并导入my_config.ini 中的配置参数,读入test作用域
Config::parse('my_config.ini','ini','test'); 

// 设置user_type参数,并纳入user作用域
Config::set('user_type',1,'user'); 

// 批量设置配置参数,并纳入test作用域
Config::set($config,'test'); 

// 读取user作用域的user_type配置参数
echo Config::get('user_type','user');

// 读取user作用域下面的所有配置参数
dump(Config::get('','user')); 
dump(config('',null,'user')); // 同上

// 判断在test作用域下面是否存在user_type参数
Config::has('user_type','test'); 
config('?user_type','test');

config()的实质是 先调用Config::xxx 再运行

config('?name','range')-->

return 0 === strpos($name, '?') ? Config::has(substr($name, 1), $range) : Config::get($name, $range);

strpos ( string $haystack , mixed $needle):返回needle在haystack中首次出现的数字位置 注意字符串位置是从0开始,而不是从1开始的。如果没找到 needle,将返回 FALSE

环境变量配置和使用


问题1:$_ENV无法获取 环境变量

打开php.ini,找到这样几行代码:
; variables_order
;Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS"
然后,将;Default Value: "EGPCS"前面的分号去掉,整个配置变成:
; variables_order
Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS"
然后重启Apache就可以了。


问题2:.env无法使用

修改thinkphp框架下的 base.php
在 putenv("$name=$val"); 代码下边
加上
$_ENV[$name] = $val;
$_SERVER[$name] = $val;


环境变量配置的参数会全部转换为大写,值为 nullnofalse 等效于 "",值为 yestrue 等效于 "1"。默认加前缀PHP_

分组配置

[database]              |等价
hostname=localhost      |database_hostname=localhost  username=root           |database_username=root 
password=root           |database_password=root 

获取环境变量的值

Env::get('database.username');
Env::get('database.password');
// 同时下面的方式也可以获取
Env::get('database_username');
Env::get('database_password');

// 获取环境变量 如果不存在则使用默认值root
Env::get('database.username','root');

可以直接在应用配置中使用环境变量,例如:

return [
    'hostname'  =>  Env::get('hostname','127.0.0.1'),
];

可在.env中创建app_status 表示开发环境 并中config目录下 建相应开发环境的 PHP文件 并编写

从而使用不同的环境变量

URL和路由

入口文件

  • thinkphp 为单入口文件 应用程序的所有http请求都由某一个文件接受并转发到功能代码中
  • 单入口优势
    - 安全检测
    - 请求过滤

地址public\index.php
必须引入框架引导文件 start.php

隐藏入口文件

即把localhost/index.php/index/index/index变

成localhost/index/index/index

视频链接 亦可参考 模块设计

入口文件的绑定

define(BIND_MODULE)的定义

define(BIND_MODULE)的定义

  1. BIND_MODULE绑定模块 只能访问绑定模块下的相关内容,若模块不存在 报错

  1. 'auto_bind_module'     => true
    开启之后  通过文件入口进入则默认  名字相同的模块
    

    注意3pictures的url

通过绑定让某个人/服务器 只能访问部分功能

路由

  • 'url_route_on'         => true,//开启路由
    ----------
    return[
            //将id变量传递给info方法
            'news/:id'  => 'index/index/info'];         //设置路由
    如此开启路由后 只可localhost/news/xxx(.html)来访问
    不可localhost/index/index/info/id/xxx.(html)访问
    当要求echo url('index/index/info',['id'=>xxx]) 时
    打印出来的是  /news/xxx.html
    
    
  • 'url_route_must'       => false//只有路由才可访问
    //启用后若未设置 则index/index/demo等失效
    	
    

请求和响应

请求对象获取 request

//3种获取request方式
public function index(Request $request)//方式1
{
    $request=request();   //方式2
    $request=Request::instance();   //方式3
    dump($request);
}

请求对象参数获取

request源文件地址:thinkphp\think\Request.php

变量类型方法包括:

方法 描述
param 获取当前请求的变量
get 获取 $_GET 变量
post 获取 $_POST 变量
put 获取 PUT 变量
delete 获取 DELETE 变量
session 获取 $_SESSION 变量
cookie 获取 $_COOKIE 变量
request 获取 $_REQUEST 变量
server 获取 $_SERVER 变量
env 获取 $_ENV 变量
route 获取 路由(包括PATHINFO) 变量
file 获取 $_FILES 变量

Request详细信息

//先定义一个对象,通过其调用方法
$request = Request::instance();
#获取浏览器输入框的值
dump($request->domain());
dump($request->pathinfo());
dump($request->path());


//路由信息
dump($request->route());
//调度信息
dump($request->dispatch());

#请求类型
dump($request->method());
dump($request->isGet());
dump($request->isPost());
dump($request->isAjax());

#请求的参数
dump($request->get());
dump($request->param());
dump($request->post());
dump($request->session());
dump($request->cookie());

dump($request->para('type'));
dump($request->cookie('mail'));

#模块   控制器   方法
dump($request->module());
dump($request->controller());
dump($request->action());

input助手函数

input 地址 thinkphp/helper.php

if (!function_exists('input')) {
    /**
     * 获取输入数据 支持默认值和过滤
     * @param string    $key 获取的变量名
     * @param mixed     $default 默认值
     * @param string    $filter 过滤方法
     * @return mixed
     */
    function input($key = '', $default = null, $filter = '')//通过接口传值
    {
        if (0 === strpos($key, '?')) {
            $key = substr($key, 1);
            $has = true;
        }
        if ($pos = strpos($key, '.')) {
            // 指定参数来源
            list($method, $key) = explode('.', $key, 2);//把$key分割为$method & $key $method为‘,’前
            if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
                $key    = $method . '.' . $key;
                $method = 'param';
            }
        } else {
            // 默认为自动判断
            $method = 'param';
        }
        
        if (isset($has)) {
            return request()->has($key, $method, $default);//有?执行has
        } else {
            return request()->$method($key, $default, $filter);//无?执行method
        }
    }
}

响应对象 Response

$data=[
    'code'   =>200,
    'result' =>[
        'userName' => 'wys',
        'userMail' => '3223905473@qq.com'
    ]
];
return dump($data);
//return $data  报错  不能直接return数组
return的默认输出格式为html
若要 return $data 的输出 需用Config::set('default_return_tpye','json')
把输出格式变成json、xml等


!!不推荐 可以建立相关文件的config 在里面修改输出格式

!!!推荐 如下代码方式

public function test($type='json')//该处可从url输入框内进行get取值
{
    if(!in_array($type,['json','xml','jsonp'])){$type='json';}  //判断文件类型合法性
    Config::set('default_return_type',$type);
    //改变文件输出格式

    $data=[
        'code'   =>200,
        'result' =>[
            'userName' => 'wys',
            'userMail' => '3223905473@qq.com'
        ]
    ];
    return $data;
}

视图和模板

视图view

 #默认模板地址
 #app/index/view/index/index.php

 #传递第一个参数  修改模板文件目录的html地址名称
 #view('xxx') …………/xxx.php
 #view('xx/xxx')  app/index/view/xx/xxx.html
 #view('./xxx')  那么就找入口文件同级开始的模板文件
 //return view();
 #传递第二、三个参数   传递内容
/* return view('',[
     'name'=>'yys',
     'email'=>'2321323@qq.com'
 ],[ 'BBIS'=>'这是向BBIS传的内容'
     ]);*/

<html>
<meta charset="UTF-8">
<h1>
    这是index.html
</h1>
 <p>{$name} </p>
<p>{$email}</p>
<p>BBIS</p>
</html>

#不建议使用view
#可以用$this ->fetch()方法相同
#也可用$this ->assign()
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
    public function index()
    {    
    $this->assign('key','this is value ->key in assign');
    return $this ->fetch('',['name'=>'yys',
            'email'=>'2321323@qq.com' ],
            [ 'BBIS'=>'这是向BBIS传的内容']);
    }
}

这是index.html

{$name}

{$email}

{$key}

BBIS

fetch 和view 都要用到html模板

可以用$this->display()(不需要)直接输出字符串 display()可接收标准的变量

$this->assign('assign','this is assign mean');
return $this->display('this is {$name} display mean {$assign}',['name'=>'yys']);

变量输出、赋值、替换

use think\Controller;
use think\View;
class Index extends Controller
{
    public function index()
    {
        $this -> assign('key','value');
        $this ->view->key2='value2';
        View::share('key3','value3');
        $this->fetch('key4','value4');
        //4种赋值
    }
}
public function __construct($engine = [], $replace = [])
{
    // 初始化模板引擎
    $this->engine($engine);
    // 基础替换字符串
    $request = Request::instance();
    $base    = $request->root();
    $root    = strpos($base, '.') ? ltrim(dirname($base), DS) : $base;
    if ('' != $root) {
        $root = '/' . ltrim($root, '/');
    }
    $baseReplace = [
        '__ROOT__'   => $root,
        '__URL__'    => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()),
        '__STATIC__' => $root . '/static',
        '__CSS__'    => $root . '/static/css',
        '__JS__'     => $root . '/static/js',
    ];
    $this->replace = array_merge($baseReplace, (array) $replace);
}

系统变量原生标签

大多数逻辑编写调整调整在控制器中完成。模板只用来展示界面的,多数时候不需要在view层> > 进行逻辑的编写。可以使用系统默认的标签件进行

详细系统变量

模板中可以直接使用系统框架提供的$Think变量,获取来自系统中所有变量的值

{$Think. server.HTTP_HOST}

{$Think.env.PHP_STATUS}

{$Think.session.email}

{$Think. cookie.name}

{$Think. get.id}

{$Think.request.id}

模板变量 变量输出 调节器

class Index extends Controller
{
    public function index()
    {
      // dump($_SERVER);
        $this->assign('email','3239090@qq.com');
        $this->assign('time',time());
        $this->assign('user','yys');
        $this->assign(['a'=>10,'b'=>12]);
        return $this->fetch();
    }
}
<p>{$email}:{$email|md5}</p>
<p>{$email}:{$email|substr=0,8}</p>
<p>{$time}:{$time|date="Y-m-d",###}</p> //####占位 传递前面的值   若是开头 可以不加###
substr($obj,a,b) 截取a~b的字符
md5($obj)
date("Y-m-d",time())

<p>{$email|default="21312213@qq.com"}</p>//若之前未赋值  则输出default后的内容

<p>a+b={$a+$b}</p>
<p>a-b={$a-$b}</p>
<p>a*b={$a*$b}</p>
<p>a/b={$a/$b}</p>
<p>a%b={$a%$b}</p>
<p>--a={--$a}</p>
<!--这里是html的注释  不会在html上显示,会产生源码-->
{/*这里是view的注释  不会在HTML上显示,也不会产生源码*/}
{literal}
  {$email}//在部分代码不会被编译  
{/literal}

模板循环标签

class Index extends Controller
{
    public function index()
    {
        $list=[
            'user'=>[
                'name'=>'yys',
                'email'=>'343243@qq.com'
            ],
            'user1'=>[
                'name'=>'wys',
                'email'=>'12312124@qq.com'
            ],
            'user3'=>[
                'name'=>'asd',
                'email'=>'123234@qq.com'
            ]
        ];
        $this ->assign('empty','here empty');
        $this ->assign('list',$list);

        return $this->fetch();
    }
}

<!--volist-->
{volist name="list" id="vo" offset="1" length="2" mod="3" empty="$empty" key="$i"}
   <p>{$vo.email}</p>
{/volist}
offset 起始位置默认0开始
mod    循环次数取余
key    循环次数 默认i
empty  数组为空时 输出
<!--foreach-->
1 {foreach $list as $vo}
<p>{$vo.name}.{$vo.email}</p>
{/foreach}
2  {foreach name="list" item="vo" key="s"}
<p>{$s}:{$vo.name}.{$vo.email}</p>
{/foreach}
key为数组下标  即例中的user  默认为key


<!--for-->
{for start="1" end="10" step="2" name="i"}
<p>{$i}</p
{/for}>

比较标签

----等于
{eq name="a" value="$b"}
<p>same</p>
{else}
<p>diff</p>
{/eq}

------不等于
{neq name="a" value="$b"}
<p>same</p>
{else}
<p>diff</p>
{/neq}

-------大于
{gt name="a" value="$b"}
<p>right</p>  //大于 right
{else}
<p>error</p>
{/gt}

---------小于
{lt name="a" value="$b"}
<p>right</p>  //小于 right
{else}
<p>error</p>
{/lt}

-------大于等于
{egt name="a" value="$b"}
<p>right</p>  //大于等于 right
{else}
<p>error</p>
{/egt}

------------小于等于
{elt name="a" value="$b"}
<p>right</p>  //小于等于 right
{else}
<p>error</p>
{/elt}


条件判断标签

-----------switch
{switch name="Think.get.level"}
    {case value="1|0"}<p>普通会员</p>{/case}
    {case value="2"}<p>铜牌会员</p>{/case}
    {case value="3"}<p>黄金会员</p>{/case}
    {case value="4"}<p>钻石会员</p>{/case}
    {default/}<p>游客</p>
{/switch}

-----------------range
{range name="Think.get.level" value="1,2,3" type="in"}
   <p>当前level是1,2,3中一个</p>
{else/}
   <p>当前level不是1,2,3中任何一个</p>
{/range}
若type="between" value 只取前2个值
type="notbetween"
type="in"
type="notin"  都有单独标签

------------defined
{defined name="APP_PATH"}
   <p>APP_PATH 已定义</p>
   {else/}
   <p>APP_PATH 为定义</p>
{/defined}

-----------if  不建议  一般用switch
{if condition="(Think.get.level==1) AND ($Think.get.id==10)"}
     <p>当前值为1 且id=10</p>
{else/}
     <p>当前值不为1 或id不等于10</p>
{/if}
AND 和OR  可以替换


模板的布局 、包含和继承

{include file "xx/xxx" /} 引入模板

{extend name="xx/xxx" /} 继承模板

{block name="xxxxx"}{/block} 在模板中设置区块 时继承后 可对相应区块 修改 一个模板区块不重名

在继承模板中使用 原区块内容

{block name="xxxxx"}
    {__block__}
{/block} 

layout机制不能使用block但是可以使用include:

首先要修改配置文件(conf/config.php)=>'template'下添加:

'layout_on' => true,//开启这个功能所有模板都有效

'layout_name' => 'layout'

其次,新建一个和index文件夹同级的layout.html文件

一个布局模板同时只能有一个特定替换字符串。

{block name="xxxxx"}
    {__block__}          => {__CONTENT__}
{/block}                    最终模板直接输入内容即可
                            若要有多个地方改变  可设置变量
                            在php中对变量赋值

详细内容见开发手册

数据库操作

数据库连接

<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
class Index extends Controller{ 
  public function index(){
    dump(Config('database'));
    $res= Db::connect();
    $res= Db::connect([
      'type'=>'mysql',
      'hostname'``=>'127.0.0.1',
      'database'=>'course',
      'usename'=>'root',
      'password'=>'root_pw',
      'hostport'=>'3306',
      'charset'=>'utf8',
      'prefix'=>''
    ]);
    $res=Db::connect('mysql://root:root@127.0.0.1:3306/course#utf8');
    dump($res);
  }

数据库查询

Db::table 需要加前缀

Db::name不需要加前缀

db()生成实例 若不生成 要加第三个参数false 不需要加前缀

<?php

namespace app\index\controller;

use think\Controller;
use think\Db;



class Index extends Controller
{
    public function index()
    {
       //dump(config('database'));
        //$res=Db::query("SELECT * FROM id_user WHERE id=?",[1]);
        ------------
        #插入信息
        //$res=Db::execute("INSERT INTO id_user SET name=?,password=?,email=?",['yys',md5('yys'),'yys@qq.com']);
        ------------------------------
        #select 返回所有记录   2维数组形式
        #如果结果不存在  返回空数组
        //$res=Db::table('id_user')->where(['id'=>100])->select();
        //$res=Db::table('id_user')->select();
------------------------------
        #find   返回1条记录    1维数组
        #如果结果不存在  返回null
       // $res=Db::table('id_user')->find();
--------------------------------------
        #value 返回1条记录   且为某个字段的值
        #如果结果不存在  返回null
        //$res=Db::table('id_user')->value('email');
-------------------
        #column   返回1维数组  为value那列的值
        #如果存在第2个参数  就返回这个数组并用第2个参数的值做key值  key=>field
        #如果结果不存在  返回空数组
        //$res=Db::table('id_user')->column('name','email');
------------------------------
        //$res=Db::name('user')->select();
        $res=\db('user',[],false)->select();
        dump($res);
    }
}

添加数据

public function index()
{
    $db=Db::name('user');
    $pwd='password';
    #insert 返回值是影响记录的行数 插入数  返回影响行数
    $res=$db->insert([
       'name'=>'ete',
       'email'=>'ete@qq.com',
        $pwd=>md5('ete')
    ]);
    dump($res);
}
public function index()
{
    $db=Db::name('user');
    $pwd='password';
    $data=[];
    for($i=1;$i<=10;$i++)
    {
    $data[]=[    //[]不要忘了
     'email'=>"{$i}@qq.com",
     $pwd=>md5("www{$i}"),
     'name'=>"{$i}"
    ];
    }
    $res=$db->insertAll($data);
    dump($res);
}

数据库更新

public function index()
{
    $db=Db::name('user');
    $pwd='password';
    $data=[];
    #update  返回影响行数
    $res=$db->where([
    'id'=>1
    ])->update([
       'name'=>'qwe'
    ])
    dump($res);
}
public function index()
{
    $db=Db::name('user');
    $pwd='password';
    $data=[];
    #setField   返回影响行数   每次更新一个字段
    $res=$db->where(['id'=>3])->setField('name','qeqw');
    dump($res);
}
 public function index()
    {
        $db=Db::name('user');
        $pwd='password';
        #setInc  每次字段内容增加key 默认为1 返回影响行数
        $res=$db->where(['id'=>1])->setInc('num',key);
        dump($res);
     }
public function index()
{
    $db=Db::name('user');
    $pwd='password';
    #setDec 每次字段内容减少key 默认为1 返回影响行数
    $res=$db->where([
        'id'=>1
    ])->setDec('num',key);
    dump($res);
}

数据删除

public function index()
{
    $db=Db::name('user');
    $pwd='password';
    #delete 返回影响行数  若where的内容为主键  可直接添加在delete()中
    #若要删除所有数据 让where输出true 如1=1
    $res=$db->where([
        'id'=>1
    ])->delete();
    dump($res);
}

条件构造器

where 条件and关系 可用数组 where([ ])

链式操作

$res =Db::table('imooc_user')
->where('id','gt',5)
->field("username,id,group")
->order('id',DESC)  //DESC为降序
->limit(3,5)
->page(2,5)//limit分页limit((m-1)*n,n)===  m:当前页数,n:每页多少条数据 
->group("'group'") //group为保留字 加单反号变为字段
//group后 order、page、limit、等失效 且每个group分类只输出1个
->select();
dump($res);

遇到问题 :

语法错误或访问冲突:1055 SELECT列表的表达式#1不在GROUP BY子句中,并且包含未聚合的列“ course.user.name”,该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by不兼容

解决方法

1、找到mysql的配置文件 my.ini (一般在mysql根目录)
2、在my.ini 中将以下内容添加到 [mysqld]下
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
3、重启mysql服务!问题解决!

 posted on 2021-01-29 15:15  夜深楼鼓  阅读(73)  评论(0编辑  收藏  举报