博客列表 >PHP 27 composer自动加载器与自撸框架(0807fri)

PHP 27 composer自动加载器与自撸框架(0807fri)

老黑
老黑原创
2020年08月17日 21:35:46637浏览

主要内容:

  1. 对象的三种加载类型
  2. composer的自动加载功能(通过json文件的映射等),也分三种
  3. composer安装并使用第三方组件或依赖库(一个验证码组件的使用)
  4. 自己搭建一个简单的框架(感觉没有看出来有啥用处,或者自己还不太懂吧)

1. 加载的三种类型

  • 首选创建下引用对象,app目录下的controller目录下的User.php文件
  1. <?php
  2. namespace app\controller;
  3. // 1. 类的命名空间与当前类文件的路径完全一致
  4. // 2. 类名称与类文件的名称完全一致
  5. // 4. 此时, 这个类就符合了PSR-4规范
  6. class User
  7. {
  8. public static function hello()
  9. {
  10. return __METHOD__;
  11. }
  12. }
  • 然后了解三种加载方式

1-1. 常规的传统加载

  1. <?php
  2. // 1. 传统方式: include / require
  3. // 加载类文件
  4. require 'app/controller/User.php';
  5. // 注册类别名[可选]
  6. use app\controller\User;
  7. // 调用类成员
  8. echo User::hello();

1-2. 自动注册加载(spl_autoload_register)

  • 然后通过设置path,并将路径转化为字符串等来进行加载
  1. <?php
  2. // 2. 注册自动加载函数
  3. // 加载类文件使用一个内置的函数来完成
  4. spl_autoload_register(function($class){
  5. // 获取类的路径名称
  6. $path = str_replace('\\', DIRECTORY_SEPARATOR, $class);
  7. // 生成一个完整的类文件名
  8. $classFile = __DIR__ . '/' . $path . '.php';
  9. // 加载类文件
  10. require $classFile;
  11. });
  12. // 注册类别名[可选]
  13. use app\controller\User;
  14. // 调用类成员
  15. echo User::hello();

1-3. 用composer自动加载

  • 这块的一些注意事项
  • 创建json文件及vendor目录等
    -> 在json文件中进行对象映射
    -> 在文件中快捷使用。具体见整个第二部分

2. 用composer自动加载

2-1. 创建json文件及vendor目录等

  • 快速创建的方式是建立一个composer.json空文件(里面就一个{})
  • 然后用命令composer install即可创建verdor及下面的autoload.php文件

2-2. 在json文件中进行对象映射

  • 这里有一个不断优化的过程,最后的方式是psr-4模式。
  • 第一种:直接的files模式。例如所有的路径及文件名。
    • 这种有一个缺点就是有多少文件就要列多少,哪怕路径是一样的。
  1. {
  2. "autoload": {
  3. "files": [
  4. "app/controller/User.php",
  5. "lib/Order.php",
  6. "lib/Goods.php"
  7. ]
  8. }
  9. }
  • 第二种:classmap模式。到目录即可,里面不进行展开。
    • 这种依然有缺点,但具体是什么也忘记了,后面慢慢琢磨吧,有无可能是一个类中有多个方法?
    • composer.json: autoload: classmap: 类映射 , 实现类的批量注册
  1. {
  2. "autoload": {
  3. "classmap": [
  4. "app/controller",
  5. "lib"
  6. ]
  7. }
  8. }
  • 第三种:psr-4模式。
  • autoload: psr-4: 类的命名空间: 类所在的路径目录 进行绑定。命名空间最后必须以”\“空间分隔符结尾。等于前面的部分显示命名空间,后面才是类所在的目录。
  1. {
  2. "autoload": {
  3. "psr-4": {
  4. "app\\controller\\": "app/controller",
  5. "phpcn\\": "lib"
  6. }
  7. },
  8. "require": {
  9. "gregwar/captcha": "^1.1"
  10. }
  11. }

以上所有的三种方法中需要注意:

  • composer.json: autoload: files: 可以加载任意位置的类文件
  • 注册完成之后, 在终端执行命令(这点很关键关键): composer dump-autoload(中间的-可以省略掉), 使files字段生效
  • 只要是composer.json中的”autoload”字段的内容发生变化, 就必须执行composer dumpautoload让它生效

2-3. 在文件中快捷使用

  1. <?php
  2. // 调用的是composer中的自动加载功能
  3. require_once __DIR__ . '/vendor/autoload.php';
  4. // 注册类别名[可选]
  5. use app\controller\User;
  6. use phpcn\Order;
  7. // 调用类成员
  8. echo User::hello();
  9. echo '<hr>';
  10. // 调用lib/Order::hello()
  11. echo Order::hello();

3. 如何在项目中使用第三方的依赖库/组件

  • 一个验证码组件的使用
  1. <?php
  2. // 1. composer require gregwar/captcha
  3. // 2. 更新composer.json中的require字段
  4. // 3. 下载包到vendor对应的目录下面
  5. // 4. 剩下就看组件包的用户手册
  6. // composer自动加载器
  7. require_once __DIR__.'/vendor/autoload.php';
  8. // 注册类
  9. use Gregwar\Captcha\CaptchaBuilder;
  10. // 创建验证器类实例/对象
  11. $captcha = new CaptchaBuilder;
  12. $captcha
  13. ->build()
  14. ->save('out.jpg')
  15. ;
  16. // 服务器端获取到验证码
  17. $_SESSION['phrase'] = $captcha->getPhrase();
  18. // 查看验证码,这块查看的目的是跟图片中的进行对照,看是否一致。
  19. // 后面要真实使用的话,肯定是需要进行验证码的匹对,然后是否允许通过:
  20. echo '验证码是: ' , $_SESSION['phrase'];
  21. ?>
  22. <!DOCTYPE html>
  23. <html lang="en">
  24. <head>
  25. <meta charset="UTF-8">
  26. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  27. <title>Document</title>
  28. </head>
  29. <body>
  30. <h3>用户登录</h3>
  31. <div>
  32. <label for="">邮箱:</label>
  33. <input type="email" name="" id="">
  34. </div>
  35. <div>
  36. <label for="">密码:</label>
  37. <input type="password" name="" id="">
  38. </div>
  39. <div>
  40. <label for="">验证码:</label>
  41. <img src="<?php echo $captcha->inline(); ?>" onclick="location.reload()" />
  42. # 点击验证码就重新生成一个新的。
  43. </div>
  44. <div>
  45. <button>提交</button>
  46. </div>
  47. </body>
  48. </html>

4. 依赖composer搭建一个php框架

  • 老师列的一些基本流程:自制 php 开发框架

4-1. 架构

  • M: Model, 使用第三方包实现
  • V: View, 使用第三方实现
  • C: Controller:业务逻辑主要是写到控制器中

4-2. 第三方包

  • Model: composer require catfan/medoo
  • View: composer require league/plates

4-3. 流程

  • 创建自己的框架核心代码, Model, View,分别继承第三方的包(放在core文件夹下,两个php文件)
  • 创建自己的应用,按 MVC 框架,并创建属于这个应用的 model, view, controller(放在app文件夹下,分别三个文件夹。因为每个里面可能不限于1个)
  • 更新 composer.json 中的类的自动的映射关系
  • 创建入口文件(index.php), 使用 composer 自动加载器进行测试

  • core下面的model.php文件

  1. <?php
  2. // 模型类
  3. namespace core;
  4. use Medoo\Medoo;
  5. // 继承自第三方包:catfan/medoo
  6. class Model extends Medoo
  7. {
  8. // 构造方法: 连接数据库
  9. public function __construct()
  10. {
  11. $options = [
  12. 'database_type' => 'mysql',
  13. 'database_name' => 'phpedu',
  14. 'server' => 'localhost',
  15. 'username' => 'root',
  16. 'password' => 'root'
  17. ];
  18. parent::__construct($options);
  19. }
  20. // 自己可以封装一些方法,创建自己的模型方法库
  21. // 获取满足条件的集合中的第一条数据
  22. public function first()
  23. {
  24. }
  25. }

  • core下面的view.php文件
  1. <?php
  2. // 视图类
  3. namespace core;
  4. use League\Plates\Engine;
  5. class View extends Engine
  6. {
  7. public $templates;
  8. public function __construct($path)
  9. {
  10. $this->templates = parent::__construct($path);
  11. }
  12. }

  • app/models下的UsersModel.php文件
  1. <?php
  2. namespace models;
  3. use core\Model;
  4. // 用户自定义模型通常与一张数据表对应
  5. class UsersModel extends Model
  6. {
  7. public function __construct()
  8. {
  9. parent::__construct();
  10. }
  11. }

  • app/views/users下的list.php文件
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>用户信息</title>
  7. <style>
  8. body {
  9. display: flex;
  10. flex-direction: column;
  11. align-items: center;
  12. }
  13. table {
  14. border-collapse: collapse;
  15. border: 1px solid;
  16. width: 50%;
  17. text-align: center;
  18. }
  19. th,
  20. td {
  21. border: 1px solid;
  22. padding: 5px;
  23. }
  24. tr:first-child {
  25. background-color: #eee;
  26. }
  27. </style>
  28. </head>
  29. <body>
  30. <h3>用户管理系统</h3>
  31. <table>
  32. <tr>
  33. <th>id</th>
  34. <th>姓名</th>
  35. <th>邮箱</th>
  36. <th>操作</th>
  37. </tr>
  38. <?php foreach ($users as $user): ?>
  39. <tr>
  40. <td><?=$this->e($user['id'])?></td>
  41. <td><?=$this->e($user['name'])?></td>
  42. <td><?=$this->e($user['email'])?></td>
  43. <td><button>编辑</button><button>删除</button></td>
  44. </tr>
  45. <?php endforeach ?>
  46. </table>
  47. <p>
  48. <a href="">1</a>
  49. <a href="">2</a>
  50. <a href="">3</a>
  51. <a href="">4</a>
  52. <a href="">5</a>
  53. <a href="">6</a>
  54. </p>
  55. </body>
  56. </html>
  • app/controllers下面的UserController.php内容
  1. <?php
  2. namespace controllers;
  3. class UsersController
  4. {
  5. // 将依赖的外对模型对象和视图对象,使用依赖注入到构造方法中,使它在控制器中共享
  6. public $model = null;
  7. public $view = null;
  8. //构造方法
  9. public function __construct($model, $view)
  10. {
  11. $this->model = $model;
  12. $this->view = $view;
  13. }
  14. // 用于测试
  15. public function index()
  16. {
  17. return __METHOD__;
  18. }
  19. // 这个相当于自己也可以创建一些东西
  20. public function select()
  21. {
  22. // 通过模型获取数据
  23. $users = $this->model->select('users', ['id', 'name','email'], ['id[>=]'=>5, 'LIMIT'=>5]);
  24. // return $users;
  25. // 将数据渲染到模板上(模板赋值同步完成)
  26. return $this->view->render('users/list', ['users'=> $users]);
  27. }
  28. }

  • 更新 composer.json 中的类的自动的映射关系
  1. {
  2. "require": {
  3. "catfan/medoo": "^1.7",
  4. "league/plates": "^3.3"
  5. },
  6. "autoload": {
  7. "psr-4": {
  8. "models\\": "app/models",
  9. "views\\": "app/views",
  10. "controllers\\": "app/controllers",
  11. "core\\": "core"
  12. }
  13. }
  14. }
  • 入口文件index.html中去实现
  1. <?php
  2. // composer加载器
  3. use controllers\UsersController;
  4. use models\UsersModel;
  5. use core\View;
  6. require_once __DIR__ . '/vendor/autoload.php';
  7. // 测试模型
  8. $model =new UsersModel();
  9. // var_dump($model);
  10. // 测试视图
  11. $view = new View('app/views');
  12. // var_dump($view);
  13. // 测试控制器
  14. $controller = new UsersController($model, $view);
  15. // var_dump($controller);
  16. // echo $controller->index();
  17. print_r($controller->select());

5. 作业与实战

  1. 实例演示comoser.json的autoload字段的files, classmap, psr-4的意义;
  2. 选做, 参考课堂案例,使用composer快速实现一个迷你的php开发框架

整体实现了一边,创建目录如下图:
后面还需要多联系,感觉很多精髓,尤其是多个文件,多个class以及多方法情况下,到底不同方法的差异、好处还没体会到(应该是越向后的方法越简单):

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议