Thinkphp

thinkphp:mvc模式

1,thinkphp的安装配置

  1. 条件
    1. PHP>=5.4.0
    2. PDO MbString CURL PHP Externsion
    3. Mysql
    4. Apache或Nginx
  2. 安装:
    • composer composer config -g repo.packagist composer https://packagist.phpcomposer.com composer create-project --prefer-dist topthink/think think_composer
    • git git clone https://github.com/top-think/think.git
    • 直接到thinkphp官网下载稳定版 5.0.24
    • 5.0.24 直接访问public文件夹即可 6.0版本访问时会报错
  3. 目录结构
    1. application 所有的应用 目录
      1. index 前台逻辑
        1. controller 模块的控制层
        2. model 新建
        3. view 新建
      2. admin 后台逻辑
      3. command.php 控制台的配置文件
      4. common.php 项目的公用文件,通用函数一般放在这里
      5. config.php 应用配置文件 admin,index 都是用它
      6. database.php 数据库
      7. route.php url
      8. tags.php 应用行为扩展文件, 埋下了很多钩子
    2. extend 第三方库
    3. public 网站根目录,都是允许访问的
      1. favicon.ico 网站图标
      2. index.php 所有请求的入口文件,都要经过index转发
      3. rebots.txt 爬虫允许文件
      4. router.php 内置的启动文件,若没有apache ,只安装了php php -s localhost:9090 router.php
      5. static 静态文件
    4. runtime 日志,缓存,编译文件
    5. thinkphp 框架文件
      1. base.php 定义常量
      2. composer.json composer文件
      3. console.php 控制台的入口文件
      4. convention.php 框架默认配置文件
      5. helper.php 助手函数,例如:Config.php --->config()
      6. lang 语言包
      7. library 框架核心
        1. traits 扩展
        2. think 框架核心
      8. PHPunit.xml 测试文件
      9. start.php 框架启动文件
    6. tpl 默认模板
      1. default_index.tpl 控制器模板文件
      2. dispatch_jump.tpl
      3. page_trace.tpl 调试模板文件
      4. think_exception.tpl 异常模板文件
    7. vendor composer 安装过程生成的目录,composer 安装的库会在这里
  4. 目录和文件开发规范
    1. 目录使用小写加下划线
    2. 所有类库函数名以“.php”结尾
    3. namespace app/index/controller; 要指明所在目录
    4. 不要使用上下划线开头
    5. 定义常量 define('APP_PATH','dev')
    6. 表和字段不能以下划线开头,命名使用下划线隔开
    7. 顶级命名空间是app,尽量不要修改
  5. 模块
    1. 修改网站根目录为public
    2. 修改.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> # 最后一行加?
    3. 此时访问localhost 即访问的是 app/controller/index/ 文件中的index控制器方法
      1. 在app下建立admin\controller/Index.php 访问时使用../admin/index/index 即可
      2. 注意common模块 不能直接使用 <?php namespace app\index\controller; use app\common\controller\Index as commonIndex; class Index { public function index() { return 'this is index Index index'; } public function common(){ $common = new commonIndex(); return $common->index(); } } ?>
  6. 配置 dump(config()); thinkphp的配置信息 /thinkphp/convention.php 全局配置
    1. 在public中增加常量定义 //定义配置文件目录 define('CONF_PATH', __DIR__ . '/../conf/'); //当前文件夹的上级文件夹下的
    2. 在/conf/中建立config.php <?php return [ 'app_author' => 'Dean', 'app_email' => '1028968939@qq.com', 'app_debug' => true, // 显示报错信息 ] ?>
    3. 此时dump后会新增
    4. 若要修改原有的值,通命名替换即可 $a = ['user'=>'a'] $b = ['user'=>'b'] dump(array_merge($a,$b)) # user 为b
    5. 扩展配置
      1. /conf/extra 建立
      2. 里边建立的xxx.php 都可作为配置文件
      3. 注意数据库database.php 放在extra中可以,放在conf下也可以 比较特殊
      4. convention -》config-》conf下一级文件-》extra目录下
  7. 场景配置
    1. 在应用配置中添加 ‘app_state' => 'home'
    2. 建立文件/conf/home.php
  8. 模块配置
    1. 为每个模块配置
    2. 建立/conf/模块名文件夹/config.php
    3. 还可以建立/conf/模块名/extra
  9. 动态配置
代码语言:javascript
复制
# 在controller中生效
# 给controller添加构造方法
public function __construct(){
    config('controller','indexController'); # 整个controll生效,放在方法中,只在方法中生效
}
  1. Config和助手函数config
    1. Config : /thinkphp/library/think/Config.php
      1. range():调整作用域
      2. parse():解析
      3. load():加载配置
      4. has():检测配置是否存在
      5. get():获取配置
      6. set():设置配置
      7. reset():重置配置参数
    2. <?php namespace app\admin\controller; class Index{ public function index(){ dump(config()); dump(\think\Congig::get()) # 或use \think\Config dump(Config::get('app_author')) # 获取对应值 config('app_author') config('xxx','yyy') # 设置值,设置失败为NULL config('xxx2','yyy2','scope') # 指定作用域,获取时也要指定,否则为空 Config::has(xxx) # xxx为null或不存在都是false # config(?xxx) } } ?>
  2. 环境变量的配置和使用
    1. <?php namespace app\admin\controller; use think\ENV class Index{ public function index(){ dump($_ENV); # 系统变量 若数组为空 在php.ini 修改 variables_order = 'EGPCS' dump($_ENV('email')) # 获取,若未定义会报错 ENV::get("email") # 此方式未定义 不报错返回NULL ENV::get("email","default") # ENV::get("database_hostname") # 可使用点语法 } } ?>
    2. /.env文件 email=1028968939@qq.com name=Dean status=dev # 在环境变量中都变PHP_大写 [database] hostname=127.0.0.1 # 名字便为 PHP_DATABASE_HOSTNAME # config.php 'app_status' => Env::get('app_status','dev'),

2,URL和路由

  1. 入口文件
    1. 单入口文件
      1. 安全监测
    2. 请求过滤 .htacccess 所有的请求经过public/index.php
  2. 入口文件绑定
    1. # public/index.php define('BIND_MODULE','admin') #此时访问localhost -->/public/index.php--->admin/(index)/(index) 默认
    2. # config.php 'auto_bind_module' => true # 开启入口文件自动绑定 此时建立/public/api.php 访问时---》/app/ap/controller/Index/index()
    3. 路由
      1. # config.php 'url_route_on' => true, 'url_route_must' => false,# 所有url都是用路由 <?php #/conf/route.php return [ 'news/:id' =>'index/index/info' ] ?> public function info($id) { url("index/index/info",['id'=>$id]) # 本方法的路由 return $id; } pathinfo 方法结束后剩余的路径信息 例如:index/index/index/a/b/c/d/e.html param(): a-->b,c->d 会传入这两个路径参数

3,请求和响应

  1. 请求对象request $request = request(); use think\Request Request::instance(); use think\Request public function index(Request $request){# 建议方式 } $request->domain();# 域名信息 $request->pathionfo(); # 路径信息 xxx/yyy/zz.html ".html"为了安全 后缀可修改 $request->path(); # xxx/yyy/zzz $request->method(); # 请求类型 $request->isGet(); # boolean $request->isPost(); # boolean $request->isAjax();# boolean $request->get() # 数组返回,5.0之后 get不包含pathinfo中的值 $request->param(); # 合并 #post同理 $request->session(); # 数组 session('name','dean'); #使用session 在convention.php中找到session,复制到config.php,删除httponly,secure $request->cookie(); cookie('email','xxxx'); $request->param('xxx'); # 获取路径参数 # 获取模块 控制器 操作 $request->module(); # 获取模块 index admin等 $request->controller(); $request->action(); $request->url() # /index/index/xxxxxx.html?id=10 包含参数 $request->baseUrl() # /index/index/xxxxxx.html 不包含参数 # input $request->input("id") # 从param()中取值 默认是get的 $request->get("id") # -------------------- $request->input("post.id") # 取出post中的id $request->post("id") # --------------------- $request->input("不存在") # NULL $request->input("不存在",'default'); $request->input(xxx,100,'intval'); # "trim" 过滤空格 # 若xxx存在,即为原来格式 不存在 会将xxx换为 int ,转换失败则为默认值为0 # ----------------------------- $request->input("session.xxxx"); # 获取session的值 # ---------------------------- # 还可以获取put,path,file,delete,patch等
  2. 响应对象Response
    1. $res = xxxxx Config::set('default_return_type','xml'); return $res; # 经过改变格式的res可直接返回,若res为对象不能直返回

4,视图和模板

  1. 视图view
    1. # 默认 app/index/view/index(控制器名)/index.html return view() return view("upload") # app/index/view/index/upload.html return view("public/upload") # app/index/view/public/upload.html # "./"表示public return view("./upload.html") # /public/upload.html return view("./html/upload.html") #/public/html/upload.html
    2. return view("index",[ 'email' => '1028968939@qq.com', # 在html中 {$email}获取 'user' => 'Dean', ],[ 'STATIC' => '当前是static的替换内容', # html中 STATIC 直接会替换 ])
    3. use think\Controller; class Index extends Controller{ public function index(){ # fetch 中第二个参数,第三个参数与view相同,html获取方也相同 $this->assign("xx","yy"); # 也可传值 return $this->fetch('upload');# /app/index/view/index/upload.html return $this->display("xx{email}xxx",[ 'email' => 'zzz' ]); # 不使用模板,直接显示字符串,不建议 } }
  2. 模板变量输出,替换,赋值
    1. use think\Controller; class Index extends Controller{ public function index(){ return $this->fetch('index',[ 'email' => 'xxx', ]); } } # {$email} ---> <?php echo $email;?> # "{}" 可在配置文件中修改template,避免与前端框架冲突 # { $email } 有空格php 不识别 $this->view->key = 'value'; # 也可传值, 获取方式与上边相同 View::share('key','value'); # 也可以
    2. # 配置文件中 'view_replace_str' => [ 'xxx' => 'yyy', ] # 在html中所有xxx都会替换为yyy # 默认的替换 # __URL__ /当前模块名、控制器名 # __STSTIC__ /static /public下边的static 用来代替静态文件地址 # __JS__ /static/js # __CSS__ /static/css # __ROOT__
    3. 模板中使用系统变量,原生标签
      1. use think\Controller; class Index extends Controller{ public function index(){ $_SERVER; # 系统变量 return $this->fetch('index'); } } <p>{$Think.server.HTTP_POST}</p> <!-- 系统变量--> <p>{$Think.env.PHP_STATUS}</p> <!-- 环境变量--> <p>{$Think.session.email}</p> <!-- session--> <p>{$Think.cookie.email}</p> <!-- cookie--> <p>{$Think.get.id}</p> <!-- get--> <p>{$Think.post.id}</p> <!-- post--> <p>{$Think.request.id}</p> <!-- request--> <p>{$Think.const.APP_PATH}</p> <!-- 常量--> <p>{$Think.APP_PATH}</p> <!-- 常量-->
      2. <!-- 在html中使用php 不建议使用--> <?php echo xxx; ?>
    4. 模板变量
      1. $this->assgin("email",'xxx'); $this->assgin("time",time()); $this->assgin("user",'dean'); <h2>{$email|md5}</h2><!-- 加密变量--> <h2>{$email|substr=0,8}</h2><!-- 字符串截取--> <h2>{$time|date="Y-m-d",###}</h2><!-- 时间格式化, ### 是占位符--> <h2>{$email|md5|strtoupper}</h2> <h2>{$a+$b}</h2><!-- 支持数字的加减乘除--> <h2>{$email|default="xxxx"}</h2><!--控制器未定义显示默认值--> {literal}{$email}{/literal} <!--不进行编译--> {/* php模板的注释 */}
    5. 循环标签
      1. $list = [ 'user1' =>['name' => 'a'], 'user2' =>['name' => 'b'], 'user3' =>['name' => 'c'], ] {volist name="list" id="vo" offset="2" length="1" mod="3" empty="xxx" key="i"} <!--从第三个开始,遍历1次,若list为空,显示empty的值,empty不接受html标签,但接受控制器变量--> <p>{$mod}</p> <!-- 0 ,1,2 间隔输出--> <p>{$i}</p> <!-- 内置变量从1开始, 有上边key控制,可修改--> <p>{$vo.name}</p> <!-- 输出abc三个--> {/volist}
      2. {foreach $list as vo} <p>{$vo.name}</p> {/foreach} {foreach name="list" item="vo" key="key"} <p>{$key}</p> <!--获取键,默认是key,通过key修改--> <p>{$vo.name}</p> {/foreach}
      3. {for start="1" end="10" step="2" name="i"} <p>{$i}</p> <!--通过name控制--> {/for}
    6. 比较标签
      1. {eq name="a" value="10"} <!-- a 是变量 不用$ ,value中使用变量时加$--> <p></p> {else} <p></p> {/eq} <!--下边用法相同--> {neq} {equal}={eq} {notequal}={neq} {gt} <!--大于--> {lt} <!--大于--> {egt} <!--大于等于--> {elt} <!--小于等于-->
    7. 条件标签
      1. {switch name = "Think.get.level"} {case value="1"}<p>普通会员</p> {case value="2"}<p>vip会员</p> {case value="3|4|5"}<p>svip会员</p> {default /}<p>游客</p> {/switch}
      2. {range name="Think.get.level" value="1,2,3,4" type="in|或者是notin|between|notbetween"} <!--level 在value中--> {else /} <!--level 不在value中--> {/range} <!--type为between时value前2个有效,包含开头结尾--> <!--效果与上边相同--> {in name="Think.get.level" value="1,2,3"} {else/} {/in} {notin},{bwtween},{notbwtween} {define name="APP_PATH"} <!--变量是否定义--> {if condition="($Think.get.level==1) AND () OR()"} {else/} {/if}
    8. 模板的包含和继承
      1. <!--nav.html--> <ul> <li></li> </ul> <!--其他地方使用--> {include file="xxxxx/nav" /}
      2. <!--base.html--> <!DOCTYPE html> <html> <head> <title>{block name="title"}模板{/block}</title> </head> <body> {block name="body"}内容{/block} </body> </html> {extend file="xxxx/base" /} {block name="title"}新的页面标题{__block__}{/block} <!--可以获取被继承的模板中的原内容-->
        1. conf/config.php 在template 中添加
          1. 'layout_on' => true
          2. 'layout_name' => 'layout'
        2. 开启后默认找的文件变为 /app/index/view/layout.html xxx {__CONTENT__} xxx <!-- 只能有一个坑,因此其他需要修改的地方 通过参数传入即可-->
        3. 此时原来/app/index/view/index/index.html 中内容随机
        4. 访问对应页面时替换地方的内容就会被替换,
        5. 前台一般使用继承,后态layout加继承

5,扩展内容