thinkphp:mvc模式
1,thinkphp的安装配置
-
条件
- PHP>=5.4.0
- PDO MbString CURL PHP Externsion
- Mysql
- Apache或Nginx
-
安装:
-
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版本访问时会报错
-
-
目录结构
-
application 所有的应用 目录
- index 前台逻辑
- controller 模块的控制层
- model 新建
- view 新建
- admin 后台逻辑
- command.php 控制台的配置文件
- common.php 项目的公用文件,通用函数一般放在这里
- config.php 应用配置文件 admin,index 都是用它
- database.php 数据库
- route.php url
- tags.php 应用行为扩展文件, 埋下了很多钩子
- index 前台逻辑
-
extend 第三方库
-
public 网站根目录,都是允许访问的
-
favicon.ico 网站图标
-
index.php 所有请求的入口文件,都要经过index转发
-
rebots.txt 爬虫允许文件
-
router.php 内置的启动文件,若没有apache ,只安装了php
php -s localhost:9090 router.php
-
static 静态文件
-
-
runtime 日志,缓存,编译文件
-
thinkphp 框架文件
- base.php 定义常量
- composer.json composer文件
- console.php 控制台的入口文件
- convention.php 框架默认配置文件
- helper.php 助手函数,例如:Config.php --->config()
- lang 语言包
- library 框架核心
- traits 扩展
- think 框架核心
- PHPunit.xml 测试文件
- start.php 框架启动文件
-
tpl 默认模板
- default_index.tpl 控制器模板文件
- dispatch_jump.tpl
- page_trace.tpl 调试模板文件
- think_exception.tpl 异常模板文件
-
vendor composer 安装过程生成的目录,composer 安装的库会在这里
-
-
目录和文件开发规范
-
目录使用小写加下划线
-
所有类库函数名以“.php”结尾
-
namespace app/index/controller; 要指明所在目录
-
不要使用上下划线开头
-
定义常量
define('APP_PATH','dev')
-
表和字段不能以下划线开头,命名使用下划线隔开
-
顶级命名空间是app,尽量不要修改
-
-
模块
-
修改网站根目录为public
-
修改.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> # 最后一行加?
-
此时访问localhost 即访问的是 app/controller/index/ 文件中的index控制器方法
-
在app下建立admincontroller/Index.php 访问时使用../admin/index/index 即可
-
注意common模块 不能直接使用
<?php namespace appindexcontroller; use appcommoncontrollerIndex as commonIndex; class Index { public function index() { return 'this is index Index index'; } public function common(){ $common = new commonIndex(); return $common->index(); } } ?>
-
-
-
配置
dump(config()); thinkphp的配置信息 /thinkphp/convention.php 全局配置
-
在public中增加常量定义
//定义配置文件目录 define('CONF_PATH', __DIR__ . '/../conf/'); //当前文件夹的上级文件夹下的
-
在/conf/中建立config.php
<?php return [ 'app_author' => 'Dean', 'app_email' => '1028968939@qq.com', 'app_debug' => true, // 显示报错信息 ] ?>
-
此时dump后会新增
-
若要修改原有的值,通命名替换即可
$a = ['user'=>'a'] $b = ['user'=>'b'] dump(array_merge($a,$b)) # user 为b
-
扩展配置
- /conf/extra 建立
- 里边建立的xxx.php 都可作为配置文件
- 注意数据库database.php 放在extra中可以,放在conf下也可以 比较特殊
- convention -》config-》conf下一级文件-》extra目录下
-
-
场景配置
- 在应用配置中添加 ‘app_state' => 'home'
- 建立文件/conf/home.php
-
模块配置
- 为每个模块配置
- 建立/conf/模块名文件夹/config.php
- 还可以建立/conf/模块名/extra
-
动态配置
# 在controller中生效
# 给controller添加构造方法
public function __construct(){
config('controller','indexController'); # 整个controll生效,放在方法中,只在方法中生效
}
-
Config和助手函数config
-
Config : /thinkphp/library/think/Config.php
- range():调整作用域
- parse():解析
- load():加载配置
- has():检测配置是否存在
- get():获取配置
- set():设置配置
- reset():重置配置参数
-
<?php namespace appadmincontroller; class Index{ public function index(){ dump(config()); dump( hinkCongig::get()) # 或use hinkConfig dump(Config::get('app_author')) # 获取对应值 config('app_author') config('xxx','yyy') # 设置值,设置失败为NULL config('xxx2','yyy2','scope') # 指定作用域,获取时也要指定,否则为空 Config::has(xxx) # xxx为null或不存在都是false # config(?xxx) } } ?>
-
-
环境变量的配置和使用
-
<?php namespace appadmincontroller; use thinkENV 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") # 可使用点语法 } } ?>
-
/.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和路由
-
入口文件
-
单入口文件
- 安全监测
-
请求过滤 .htacccess 所有的请求经过public/index.php
-
-
入口文件绑定
-
# public/index.php define('BIND_MODULE','admin') #此时访问localhost -->/public/index.php--->admin/(index)/(index) 默认
-
# config.php 'auto_bind_module' => true # 开启入口文件自动绑定
此时建立/public/api.php 访问时---》/app/ap/controller/Index/index()
-
路由
-
# 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,请求和响应
-
请求对象request
$request = request();
use thinkRequest Request::instance();
use thinkRequest 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等
-
响应对象Response
-
$res = xxxxx Config::set('default_return_type','xml'); return $res; # 经过改变格式的res可直接返回,若res为对象不能直返回
-
4,视图和模板
-
视图view
-
# 默认 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
-
return view("index",[ 'email' => '1028968939@qq.com', # 在html中 {$email}获取 'user' => 'Dean', ],[ 'STATIC' => '当前是static的替换内容', # html中 STATIC 直接会替换 ])
-
use thinkController; 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' ]); # 不使用模板,直接显示字符串,不建议 } }
-
-
模板变量输出,替换,赋值
-
use thinkController; 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'); # 也可以
-
# 配置文件中 'view_replace_str' => [ 'xxx' => 'yyy', ] # 在html中所有xxx都会替换为yyy # 默认的替换 # __URL__ /当前模块名、控制器名 # __STSTIC__ /static /public下边的static 用来代替静态文件地址 # __JS__ /static/js # __CSS__ /static/css # __ROOT__
-
模板中使用系统变量,原生标签
-
use thinkController; 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> <!-- 常量-->
-
<!-- 在html中使用php 不建议使用--> <?php echo xxx; ?>
-
-
模板变量
-
$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模板的注释 */}
-
-
循环标签
-
$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}
-
{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}
-
{for start="1" end="10" step="2" name="i"} <p>{$i}</p> <!--通过name控制--> {/for}
-
-
比较标签
-
{eq name="a" value="10"} <!-- a 是变量 不用$ ,value中使用变量时加$--> <p></p> {else} <p></p> {/eq} <!--下边用法相同--> {neq} {equal}={eq} {notequal}={neq} {gt} <!--大于--> {lt} <!--大于--> {egt} <!--大于等于--> {elt} <!--小于等于-->
-
-
条件标签
-
{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}
-
{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}
-
-
模板的包含和继承
-
<!--nav.html--> <ul> <li></li> </ul> <!--其他地方使用--> {include file="xxxxx/nav" /}
-
<!--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} <!--可以获取被继承的模板中的原内容-->
-
conf/config.php 在template 中添加
- 'layout_on' => true
- 'layout_name' => 'layout'
-
开启后默认找的文件变为 /app/index/view/layout.html
xxx {__CONTENT__} xxx <!-- 只能有一个坑,因此其他需要修改的地方 通过参数传入即可-->
-
此时原来/app/index/view/index/index.html 中内容随机
-
访问对应页面时替换地方的内容就会被替换,
-
前台一般使用继承,后态layout加继承
-
-
-