ThinkPHP6入门指南 安装框架 自从ThinkPHP5.1之后只能通过Composer安装框架了. 所以在此之前我们需要先安装Composer. 对于Winodws用户,直接下载exe安装即可 地址: https://getcomposer.org/Composer-Setup.exe 对于Linux或Mac os用户使用以下两行命令 curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer 安装完成后,我们可以把镜像换成国内源 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 这样我们的Composer就安装完成了.下面开始安装我们的Tp6. composer create-project topthink/think demo 这里的 demo 是目录名.也就是我们的根目录 稍等片刻之后,框架就已经安装完成了. 如何运行起来呢? 方法1: cd public php -S localhost:8000 方法2 php think run 随便选一种方式启动即可.这里的两种方式都只适用于开发环境.不可用于线上 之后打开浏览器进入 http://localhost:8000/ 会看到欢迎页面,那么现在已经完成ThinkPHP6.0的安装了.开发规范及目录结构 使用了框架就要遵守一定的规范. 现代PHP框架也都基于PSR规范.下面简单罗列几个点 目录命名采用小写+下划线的方式 类文件采用大驼峰命名规则 例如: BaseController.php 方法名采用小驼峰命名规则 例如: getUserInfo 函数名使用蛇形命名法 例如: get_user_info 类名应保持和文件名一致的规范 类的属性应采用小驼峰命名规则 常量以大写字母和下划线命名 例如: API_KEY 框架内配置参数以小写字母和下划线命名 遵守这些规则可以避免一些不必要的错误发生. 下面说下框架的目录结构 app 应用目录 我们大部分的代码在这里编写 config 配置目录 extend 扩展类库目录 pulic WEB目录(对外访问目录), 在配置Nginx或Apache的时候root目录指向这里 route 路由定义目录 runtime 应用的运行时目录,里面存放着运行的缓存和日志 vendor Composer类库目录 view 视图目录 think 环境变量示例文件 .example.env 环境变量示例文件,使用时应拷贝一份命名成.env TP6安装完成后,默认是单应用模式 再编写类CMS系统的时候,需要前台和后台两部分.可以将目录结构可以参考下面的结构进行调整 . 根目录 ├─app 应用目录 │ ├─index 前台目录 │ │ ├─common.php 函数文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录 │ │ ├─view 视图目录 │ │ ├─config 配置目录 │ │ ├─route 路由目录 │ │ └─ ... 更多类库目录 │ ├─admin 后台目录 │ │ ├─common.php 函数文件 │ │ ├─controller 控制器目录 │ │ ├─model 模型目录 │ │ ├─view 视图目录 │ │ ├─config 配置目录 │ │ ├─route 路由目录 │ │ └─ ... 更多类库目录 │ ├─common.php 公共函数文件 │ └─event.php 事件定义文件 上面的目录结构就是多应用的布局,其中还可以细分出更多的目录进行代码架构,比如Service、Dao、Manager,再之后的深入中会详细介绍. 如果使用多应用模式,需要安装扩展think-multi-app composer require topthink/think-multi-app 重点: 多应用模式部署后,记得删除app目录下的controller目录(系统根据该目录作为判断是否单应用的依据)第一个页面: Hello World! 了解了目录结构后,我们可以开始编写第一行代码了! 再编写前我们先让它运行起来! 直接在命令行中输入 php think run 即可启动 (别告诉我你不知道在哪个目录运行) 打开浏览器输入 http://localhost:8000/ 出现这个页面就代表启动成功啦. 下面我们去修改它,让它显示出Hello World! 找到 app/controller下的Index.php文件, 这里就是首页的默认控制器和方法. index方法里返回的就是我们最开始打开的页面内容,现在我们将他修改成Hello World! error('未找到用户') 就可以显示出'未找到用户'页面的提示了.当然你也可以通过 $this->success('登录成功') 来提示用户登录成功 下面贴一段伪代码 use app\BaseController; class Login extends BaseController { public function login() { $userInfo = (....); // 通过用户传入数据从数据库获取账号信息 if ( !$userInfo ) $this->error('登录失败'); (....) // 省略 $this->success('登录成功'); } } 渲染模板 在编写完Hello,World后.我们可以试想一下,如何输出一个html页面. 按照之前直接return字符串一样,我们也可以直接返回html代码. return '

HELLO,WORLD

'; 但是这种并不能应用在我们实际的项目中. 我们可以使用框架自带的助手函数view渲染页面. 也可以使用 View::fetch 方法 'Think', ]; 把type类型改为 php 就行了. 好啦.又抛出一个新异常了 模板文件不存在: demo\view\index\index.html 这里我们还没定义模板文件,按照框架约定可以把html放到view目录下对应控制器名的对应方法名文件中. view\index\index.html = view\控制器名\方法名.html 这里的文件后缀名和目录都是可以更改的. 第一个页面

Hello,World

再次访问,页面中又出现了我们的Hello,World.获取用户提交参数 我们已经实现了两种Hello,World的输出方式.但是不灵活啊! 现在想让他通过提交的参数输出内容该怎么实现呢? 比如提交一个name参数:小黄 页面上显示出 hello,小黄. 在显示之前.我们需要获取到这些参数. $_GET 或 $_POST 可以获取到参数. 但是我们在框架中禁止使用! Tp6给了我们几种获取方式. param('name')); var_dump(Request::param('name')); } } 我们打开浏览器,访问http://localhost:8888/?name=小黄 页面打印出3条 小黄,我们已经成功接收参数 input方法详解 input('?get.name'); // 判断 get 请求下name参数是否存在 input('get.'); // 获取所有get请求参数 input('name'); 获取name参数(包括get post请求) 还可以传入参数进行一定修饰,用于简单过滤变量.对于参数的校验最好使用验证器 Request::get('id/d'); // 强制转换为整型类型 input('post.name/s'); // 强制转换为字符串类型 request()->param('ids/a'); // 强制转换为数组类型 还有很多种获取方法.如果想了解可以去官方文档查找. 但是最终都要做到一点. 不相信任何用户传来的数据 . 可能传递过来的是一条sql注入语句,又或者是getshell.一定要严判断! 继续实现我们的需求! assign('name', $name); } } input('name/s', 'World'): 接收一个name参数, 如果没有则默认为'World' view()->assign('name', $name): 模板中的变量(除了一些系统变量外)必须先进行模板赋值后才能使用,可以使用assign方法进行全局模板变量赋值. 为什么我们的模板中不能直接使用php变量呢? (作为一个思考题) 第一个页面

Hello,

如果安装了模板引擎 可以使用模板方法 {$name} 输出变量. 访问http://localhost:8888/?name=小黄 , 页面中已经显示出 Hello, 小黄 . 我们传递一串js脚本过去: http://localhost:8888/?name= 居然执行成了.弹出了一个1 . 这种如果在加以利用是不是可以获取到我们的cookies呢? 细思极恐啊! 所以要做好用户传参验证和过滤!状态的存储-session 大部分web应用是有状态的.何为有状态呢? 一个用户在某个网站登录后,刷新页面后登录状态还保持着.这就是状态.那么服务端是如何实现的呢? Session是服务器端技术,服务器在运行时可以为每一个用户创建一个其独享的session文件,所以用户在访问服务器web资源时,可以把各自的数据放在各自的session中,当用于再去访问该服务器中其他web端资源时,其他web端再从session取出用户各自的数据; 继续以上篇的举例.我们通过name参数访问页面.会显示对应的Hello,(name的值), 我们希望访问过一次后服务器会记住上一次传入的name值.也相当与保存状态. 在tp6中使用session需要在全局的中间件定义文件中加上下面的中间件定义 'think\middleware\SessionInit' 然后就可以使用啦 use think\facade\Session; Session::set('name', 'thinkphp'); Session::get('name'); 当然也提供了助手函数 session('name', null); // 删除 name session('name'); // 取值 session('name', 'a'); // 设置内容 下面开始编码. assign('name', $name)->assign('lastName', $lastName); } } 页面: 第一个页面

Hello, [上次传入的name是: ]

我们测试下, 打开浏览器输入 http://localhost:8888/?name=xiaohuang Hello, xiaohuang [上次传入的name是: ] 由于是第一次打开页面没有上一次的输入所以这里没有显示 $name = input('name/s', 'World'); session('name', $name); 这一次输入的xiaohuang 已经被存入session中. 下次就可以通过 session('name') 获取到上次输入内容.路由 之前我们一直在首页操作,首页默认指向app/controller/Index类的index方法. 为什么能直接指向呢?在config目录下route.php中定义了这么两行指向了默认的控制器 // 默认控制器名 'default_controller' => 'Index', // 默认操作名 'default_action' => 'index', 当然你也可以通过 http://域名/index/index 访问首页 我们在新增一个方法index2 public function index2() { return "index2"; } 打开浏览器访问 http://localhost:8000/index/index2 显示出 index2. 我们如何美化这个url呢? 比如我直接访问 /index2 就能访问到我们上面定义的index2方法呢 这就得用上我们的路由了, 在route目录下有个app.php 这里就是定义整个项目的路由文件. 里面默认提供了两个测试的. use think\facade\Route; Route::rule('路由表达式', '路由地址', '请求类型'); 我们先定义一个指向index2方法的路由 Route::rule('index2', 'index/index2'); 定义之后原来的访问地址会自动失效,我们再次访问 /index2 页面也返回正常了.还可以通过/index2.html来访问.这也是因为route.php的配置文件中有声明伪静态后缀 // URL伪静态后缀 'url_html_suffix' => 'html', 它还提供了几种其他方法来对应请求类型 Route::get(); // 定义GET请求路由规则 Route::post(); // 定义POST请求路由规则 Route::put(); // 定义PUT请求路由规则 Route::delete(); // 定义DELETE请求路由规则 Route::any(); // 所有请求都支持的路由规则 这里就简单的定义了路由.现在有一套流行的规范-RESTful API. 这里不做过多介绍,外链一篇文章 RESTful API 最佳实践 针对RESTful路由我们可以设置变量 动作 URI 路由 GET /photos/{id} (通过ID查看相片) Route::get('photos/:id','Photos/show'); 我们就可以在Photos类中的show方法里接收id参数 public function index2($id) { return "接收到参数: " . $id; } 有些情况下变量用[ ]包含起来后就表示该变量是路由匹配的可选变量。这点不懂的可以动手试试.中间件 中间件主要用于拦截或过滤应用的HTTP请求. 中间件的本质是一个洋葱模型 图中的顺序为按照 Middleware A -> Middleware B 的顺序组织着 我们可以注意到当中间的横线穿过 Core App,又回到了 Middleware B,为一个嵌套模型,那么实际的顺序其实就是: Request -> Middleware A -> Middleware B -> Core App -> Middleware B -> Middleware A -> Response 定义中间件 php think make:middleware Check 这个指令会 app/middleware目录下面生成一个Check中间件。 Middleware A -> Core App Middleware A 部分 public function handle($request, \Closure $next) { // 添加中间件执行代码 return $next($request); } 后置中间件 对应于上图的 Core App -> Middleware A -> Response Middleware A 部分 public function handle($request, \Closure $next) { $response = $next($request); // 添加中间件执行代码 return $response; } 全局中间件 在app目录下面middleware.php文件中定义,我们之前启动session的时候就已经说到了. 通常还会配合路由定义中间件 Route::group('hello', function(){ Route::rule('hello/:name','hello'); })->middleware('check'); 还有控制器中间件只需要在控制器中定义middleware属性 protected $middleware = ['check']; 那么说了这么多,中间件具体有什么实际用途呢? 权限验证 添加跨域响应头 记录日志 还有很多实际用途,其根本也是降低了系统的耦合.数据库 缓存 扩展: 控制反转(IoC)及依赖注入(DI) 总结