博客列表 >使用composer自定义开发框架

使用composer自定义开发框架

longlong
longlong原创
2020年08月10日 15:38:031109浏览

1. 类加载的三种方式

示例将在frame这个目录下进行,先创建子目录app,在创建app的子目录controller,在controller里面新建文件Controller.php,在frame根目录下创建index1.php

  • Controller.php 如下:
  1. <?php
  2. namespace app\controller;
  3. class Controller
  4. {
  5. public static function hello()
  6. {
  7. return '方法名是: '.__METHOD__;
  8. }
  9. }

1.1 方式一:require

  • index1.php 如下:
  1. <?php
  2. require __DIR__."/app/controller/Controller.php";
  3. use app\controller\Controller;
  4. echo Controller::hello();

1.2 方式二:注册自动加载器

  • index2.php 如下:
  1. <?php
  2. spl_autoload_register(function ($class) {
  3. $path = str_replace("\\",DIRECTORY_SEPARATOR,$class);
  4. $classFile = __DIR__.DIRECTORY_SEPARATOR.$path.".php";
  5. require $classFile;
  6. });
  7. use app\controller\Controller;
  8. echo Controller::hello();

1.3 方式三:使用composer的autoload

  • 先生成composer.json,内容为空,就一对花括号{}

  • 执行终端命名 composer install,成功以后会自动生成vendor目录,目录下有个autoload.php

  • 在入口文件中引入autoload.php

  • 修改composer.json的属性

  1. {
  2. "autoload": {
  3. "files": [
  4. "app/controller/Controller.php"
  5. ]
  6. }
  7. }
  • 终端执行命名composer dumpautoload

  • index3.php 如下:

  1. <?php
  2. require __DIR__."/vendor/autoload.php";
  3. use app\controller\Controller;
  4. echo Controller::hello();

2. autoload 字段的意义

2.1 files 字段:加载任意位置的类文件

接上面的示例,在frame目录下,再创建子目录lib,新建文件Test1.php,如下:

  1. <?php
  2. namespace test;
  3. class Test1
  4. {
  5. public static function show ()
  6. {
  7. return '方法名是: '.__METHOD__;
  8. }
  9. }
  • 修改composer.json,如下:
  1. {
  2. "autoload": {
  3. "files": [
  4. "app/controller/Controller.php",
  5. "lib/Test1.php"
  6. ]
  7. }
  8. }
  • 执行终端命名composer dumpautoload

  • index4.php 如下:

  1. <?php
  2. require __DIR__."/vendor/autoload.php";
  3. use app\controller\Controller;
  4. use test\Test1;
  5. echo Controller::hello(),'<br>';
  6. echo Test1::show();

  • 小结:想要使用某个类,直接在files字段中加入相应的类文件路径即可,修改后记得执行终端命名

2.2 classmap 字段:类映射,实现类的批量注册

接上面示例,如果同目录下有很多的类,每次都去手动引入类文件比较麻烦,而使用classmap ,可以将类文件映射到路径上,同目录下的类文件只需要引入一次即可

示例:在上面示例的lib目录下,再新建文件Test2.php,如下:

  1. <?php
  2. namespace test;
  3. class Test2
  4. {
  5. public static function show ()
  6. {
  7. return '方法名是: '.__METHOD__;
  8. }
  9. }

如果按照files字段,需要在composer.json中再去增加lib/Test2.php,显然这样有点麻烦了,而使用classmap 呢,如下:

  1. {
  2. "autoload": {
  3. "classmap": [
  4. "app/controller",
  5. "lib"
  6. ]
  7. }
  8. }
  • 终端执行命名composer dumpautoload

  • index4.php,如下:

  1. <?php
  2. require __DIR__."/vendor/autoload.php";
  3. use app\controller\Controller;
  4. use test\Test1;
  5. use test\Test2;
  6. echo Controller::hello(),'<br>';
  7. echo Test1::show(),'<br>';
  8. echo Test2::show(),'<br>';

2.3 psr-4字段:将类命名空间与路径绑定

在开发中,类文件一般会满足两个条件:

  • 类的命名空间和当前类文件的路径一致

  • 类名与类文件名一致

这种命名规范可以叫做psr-4规范,而满足这种规范的,一般都会使用psr-4字段来实现映射

  • 修改composer.json,如下:
  1. {
  2. "autoload": {
  3. "psr-4": {
  4. "app\\controller\\": "app/controller",
  5. "test\\": "lib"
  6. }
  7. }
  8. }

3. 自定义框架

本次示例,新建frame2这个根目录,所有文件将存放在这个目录下,使用MVC架构,Model和View使用第三方包,业务逻辑写在Controller中

  • 下载模型包:catfan/medoo,终端输入命令composer require catfan/medoo

  • 下载视图包:league/plates,终端输入命令composer require league/plates

  • 创建自己的框架核心代码,继承第三方包,放入frame2/core目录下

Model.php :

  1. <?php
  2. namespace core;
  3. // 模型类
  4. // 继承第三方包catfan\medoo
  5. use Medoo\Medoo;
  6. class Model extends Medoo
  7. {
  8. // 连接数据库
  9. public function __construct(){
  10. $options=[
  11. 'database_type' => 'mysql',
  12. 'database_name' => 'first',
  13. 'server' => 'php.edu',
  14. 'username' => 'root',
  15. 'password' => 'root'
  16. ];
  17. parent::__construct($options);
  18. }
  19. }

View.php :

  1. <?php
  2. namespace core;
  3. use League\Plates\Engine;
  4. class View extends Engine
  5. {
  6. private $templates;
  7. public function __construct($path)
  8. {
  9. $this->templates = parent::__construct($path);
  10. }
  11. }
  • 创建自己的应用,分别放于app/models、app/views、app/controllers目录下

app/models中StudentModel.php

  1. <?php
  2. namespace app\models;
  3. use core\Model;
  4. class StudentModel extends Model
  5. {
  6. public function __construct(){
  7. parent::__construct();
  8. }
  9. }

app/controllers中StudentController.php

  1. <?php
  2. namespace controllers;
  3. class StudentController
  4. {
  5. // 依赖注入
  6. private $model = null;
  7. private $view = null;
  8. public function __construct($model,$view)
  9. {
  10. $this->model = $model;
  11. $this->view = $view;
  12. }
  13. // 用来测试的
  14. public function test(){
  15. echo '111';
  16. }
  17. // 查询
  18. public function select()
  19. {
  20. // 获取数据
  21. $users = $this->model->select("student", ["username","age","tel"], [ "id[>=]" => 1200,"LIMIT"=>10]);
  22. // return $users;
  23. // 渲染模板(同时进行模板赋值)
  24. return $this->view->render('student/list', ['users'=> $users]);
  25. }
  26. }

app/views/student中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>Document</title>
  7. <style>
  8. table {
  9. width: 500px;
  10. border: 1px solid black;
  11. border-collapse: collapse;
  12. text-align: center;
  13. margin: auto;
  14. }
  15. th,
  16. td {
  17. border: 1px solid black;
  18. padding: 8px;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <table>
  24. <caption>
  25. <h2>用户管理</h2>
  26. </caption>
  27. <thead>
  28. <tr>
  29. <th>用户名</th>
  30. <th>年龄</th>
  31. <th>电话</th>
  32. <th>操作</th>
  33. </tr>
  34. </thead>
  35. <tbody>
  36. <?php foreach ($users as $user): ?>
  37. <tr>
  38. <td><?=$this->e($user['username'])?></td>
  39. <td><?=$this->e($user['age'])?></td>
  40. <td><?=$this->e($user['tel'])?></td>
  41. <td>
  42. <button>编辑</button>
  43. <button>删除</button>
  44. </td>
  45. </tr>
  46. <?php endforeach ?>
  47. </tbody>
  48. </table>
  49. </body>
  50. </html>
  • 命名空间与路径绑定,实现类映射composer.json
  1. {
  2. "require": {
  3. "catfan/medoo": "^1.7",
  4. "league/plates": "^3.3"
  5. },
  6. "autoload": {
  7. "psr-4": {
  8. "app\\models\\": "app/models",
  9. "core\\": "core",
  10. "controllers\\": "app/controllers",
  11. "views\\": "app/views"
  12. }
  13. }
  14. }
  • 入口文件index.php
  1. <?php
  2. // composer 加载器
  3. // 创建入口文件,实现类加载
  4. require __DIR__."/vendor/autoload.php";
  5. use app\models\StudentModel;
  6. use core\View;
  7. use controllers\StudentController;
  8. // 测试模型
  9. $model = new StudentModel();
  10. // var_dump($model);
  11. // 测试视图
  12. $view = new View('app/views');
  13. // var_dump($view);
  14. // 测试控制器
  15. $controller = new StudentController($model,$view);
  16. // var_dump($controller);
  17. // $controller->test();
  18. print_r($controller->select());
  • 运行入口文件后效果:

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