文件目录结构
注意:
- common无法通过url直接访问,安全性高。tp把他定义为公共模块。
可通过引用来使用其下的控制器。比如:
<?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();
}
}
我们可以在common中编写一个顶级类,然后供其他模块类继承,做到代码重复利用。比如权限校检。
- tp5版本发生了很多变化,控制器命名无需加后缀Controller.
修改application目录
为了操作方便,将文件夹applicaiton重命名为app,
找到public目录下的index.php,打开将applicion修改为app.
define('APP_PATH', __DIR__ . '/../app/');
TinkPhp5配置
惯例配置:
- 配置文件设置
1、打开public目录下的index.php,修改为:
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../app/');
//定义配置文件目录
define('CONF_PATH',__DIR__.'/../conf/'); // 增加的代码
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
2、在app同级目录下新建一个conf文件夹,用于配置文件存放。
3、框架惯例配置文件所在目录:/thinkphp/convention.php.
应用配置
我们建议不能直接修改框架的配置文件,防止框架升级的时候带来很多不便。
因此我们可以配置自己的配置文件,在上述建立的conf文件夹下面新建config.php(文件名必须是这样)
配置文件的编写很简单,在config.php中返回一个数组即可。
例如:
return [
//数据库配置信息
'host' => '127.0.0.1',
'port' => '3306',
'name' => 'root',
'charset' => 'utf8',
'dbname' => 'database'
];
我们可以发现,这个配置文件在每个应用模块中都生效了。应用程序配置文件会覆盖掉框架默认配置(但是不会真正的把框架配置文件改掉,而是在运行的时候把两个配置文件做比较后存放在内存中。)
扩展配置
一般情况下,上述配置无法满足程序配置需求,因为配置项目太多,不方便维护,于是又有了扩展配置的概念。
操作方法:
- 在app同级conf文件夹下建立extra文件夹(注意文件名是规定死的)
- 然后自行建立配置文件
值得一提的是,thinkphp允许在conf目录下建立数据库配置文件:database.php,而不需要写入config.php或者extra目录下,这个是例外情况,因为每个程序都会要配置数据库。
注意一个问题:配置文件优先性:extra>config.php>convention.php
场景配置
适用于多工作场景的开发环境设置,比如在家里数据库配置和在公司的数据库配置是不同的,那么thinkphp支持我们这样配置。
具体操作方法:
- 在应用程序配置文件config.php中增加以下选项。
‘app_status’ => 'home' 或者 ‘app_status’ => 'office'
-
在config.php同级新建一个home.php或者office.php
-
在场景配置文件home.php或者office.php中增加以下代码
return [
‘app_address’ => 'home'
// 或者 ‘app_address’ => 'office'
在这里根据场景配置别的项目:
,,,,,,,,,,,,,
注意如果要配置数据,需要配置全部项目
];
模块配置
之前讲的都是全局配置,针对整个项目有效,现在来讲以下针对某个具体模块的配置,只在模块中生效。
操作方法:
- 在conf文件夹下按模块名建立一个新的文件夹,比如index,然后新建一个文件config.php(文件名是规定好的)
- 然后在config.php中配置,也是返回一个数组
我们在模块中dump配置文件发现,只在对应的模块中存在相应的配置。也就是说在index模块中的配置不会再admin中生效。
同样,我们可以在模块配置中新建extra扩展配置,原理和之前讲的一样。
动态配置
在一个类或者一个方法下的配置。
操作方法:
在类中构造函数下添加如下代码:
public function __construct()
{
config('name','jim'); //动态配置语句
}
配置对类下面所有方法均生效。如果 配置语句加入到一个方法当中,那么配置仅仅对该方法生效。
URL和路由
1、隐藏入口文件
- 打开apache的配置文件(httpd.conf)修改 :
a、 启用:LoadModule rewrite_module modules/mod_rewrite.so
b、 < Directory > 找到根目录下的 AllowOverride none ,如果是none 改成all
- thinkphp 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] //这条规则的意思是把index.php之前的内容全部定向到index.php/$1
</IfModule>
2、入口文件的绑定
打开public 文件夹下的index.php,添加:define(‘BIND_MODULE’,‘admin’);
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../app/');
//定义配置文件目录
define('CONF_PATH',__DIR__.'/../conf/');
//绑定入口文件
define('BIND_MODULE','admin');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
3、路由
请求和相应
- 请求对象获取
有三种方式获取:
1、通过助手函数:$rs=request();
2、通过request实例: $r=Request::instance();
3、传参()
public function index(Request $re)
{
dump($re);
}
- 请求对象参数获取
#获取浏览器输入框的值
dump($re->domain());
dump($re->pathinfo());
dump($re->path());
#请求类型
dump($re->method());
dump($re->isGet());
dump($re->isPost());
dump($re->isAjax());
#请求参数
dump($re->get());
dump($re->param());
dump($re->post());
dump($re->session());
dump($re->cookie());
dump($re->param('type'));
dump($re->cookie('email'));
#获取模块,控制器,方法
dump($re->module());
dump($re->controller());
dump($re->action());
视图和模板
1、默认视图路径:app/index/view/index/index.html
控制器和视图数据交换的方法:
- 助手函数:view();
- controllerl类成员函数:fetch()
- controllerl类成员函数:assign()
- controllerl类成员函数:display()
模板变量输出,赋值,替换
在控制器中通过相应的方法给模板传递变量值
$this->assign('key','value');// use think\Controller;
$this->view->key2='value2'; // use think\View;
View::share('key3','value3');
return $this->fetch('index',[
'email'=>'414972201@qq.com'
]);
系统变量原生标签
<p>{$Think.server.HTTP_HOST}</p>
<p>{$Think.env.PHP_STATUS}</p>
<p>{$Think.session.XXX}</p>
<p>{$Think.cookie.XXX}</p>
<p>{$Think.get.id}</p>
<p>{$Think.request.id}</p>
<p>{$Think.post.id}</p>
<p>{$Think.const.APP_PATH}</p>
变量输出调节器
<div>{$email|md5}</div>
<div>{$email|md5|strtoupper}</div> (连续使用函数的方式)
<div>{$email|substr=0,8}</div> (第一个参数是变量可以省略)
<div>{$email|substr=###,0,8}</div> (参数可以使用###替换)
<div>{$time|date="Y-m-d",###}</div>
<div>{$a+$b*$c}</div> (可以使用运算符)
<div>{++$a}</div>
<div>{$email|default="1777986@qq.com"}</div> (可以设置默认值)
{literal}中间内容不解析{/literal}
{/*这里是注释内容 */} 外面不显示
模板循环标签
方式1:volist
{volist name="list" id="vo" offset="0" length="3" mod="2" empty="这里没有数据" key='s'}
<p>{$s}</p>
<p>{$mod}</p>
<p>{$vo.name}</p>
{/volist}
offset:偏移,从什么位置开始循环
length:循环长度
mod:当前循环次数和mod取余
empty:当数组为空时显示的内容
s:当前循环次数
方式2:foreach
{foreach $list as $vo}
<p>{$key}</p>
<p>{$vo.name}</p>
<p>{$vo.email}</p>
{/foreach}
{foreach name="list" item="vo" key="s"}
<p>{$key}</p>
<p>{$vo.name}</p>
<p>{$vo.email}</p>
{/foreach}
方式3:for
<ul>
{for start="1" end="10" step="2" name="i"}
<li>{$i}</li>
{/for}
</ul>
比较标签
{eq name="a" value="$b"} 等鱼
<div>相等</div>
{else/}
<div>不相等</div>
{/eq}
{neq name="a" value="10"} 不等鱼
<div>不相等</div>
{else/}
<div>相等</div>
{/neq}
{gt name="a" value="$b"} 大鱼
<div>正确</div>
{else/}
<div>错误</div>
{/gt}
{lt name="a" value="10"} 小鱼
<div>正确</div>
{else/}
<div>错误</div>
{/lt}
{elt name="a" value="10"} 小鱼等鱼
<div>正确</div>
{else/}
<div>错误</div>
{/elt}
条件判断符号
{switch name="Think.get.level"}
{case value="1"}<p>青铜</p>{/case}
{case value="2"}<p>白银</p>{/case}
{case value="3"}<p>黄金</p>{/case}
{case value="3"}<p>钻石</p>{/case}
{/switch}
{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:in, notin ,between, notbetween
{defined name="APP_PATH"}
<p>已经定义</p>
{else/}
<p>没有定义</p>
{/defined}
{if condition="($Think.get.level==1) AND )"}
{else/}
{/if}
模版的布局 :包含和继承
第一种:模板的包含
如下图:应用语法:{include file=“common/nav” /}
第二种:模板的继承:
父模板中,没被改写的部分将默认显示在子模板中
如何使用父模板中默认内容:
在子模板中添加父模板默认内容使用: { __ block __ }
第三种方式:layout
- 首先要修改应用程序配置文件
在conf目录中
'layout_on' => 'true',
'layout_name' => 'layout'
-
在view 目录下建立layout.html文件
-
将需要替换的部分使用:{__ CONTENT __} 替换。
-
在子模板中直接填写内容
应用总结:
前台开发一般使用继承的方式,因为变化比较大
后台开发继承结合layout方法