博客列表 >0217服务容器与路由

0217服务容器与路由

曾
原创
2020年03月03日 23:49:20722浏览

服务容器

可以理解为当一个项目需要使用到多个参数来传递数据的时候,为此而创建的一个类。
例:一个表单输出项目
先创建一个model脚本

  1. <?php
  2. namespace test;
  3. use PDO;
  4. class Model
  5. {
  6. public function getData()
  7. {
  8. return (new PDO('mysql:host=localhost;dbname=phpedu','root','root'))->query('SELECT * FROM user')
  9. ->fetchAll(PDO::FETCH_ASSOC);
  10. }
  11. }

再来一个view脚本

  1. <?php
  2. namespace test;
  3. class View
  4. {
  5. public function fetch($data)
  6. {
  7. $table = '<table>';
  8. $table .='<caption>门派信息</caption>';
  9. $table .='<tr><td>姓名</td><td>门派</td><td>职务</td></tr>';
  10. foreach ($data as $value){
  11. $table .='<tr><td>'. $value['name'] .'</td><td>'. $value['school'] .'</td><td>'. $value['job'] .'</td>';
  12. $table .='</tr>';
  13. }
  14. return $table;
  15. }
  16. }
  17. echo '<style>
  18. table{
  19. margin:auto;
  20. width:200px;
  21. height:150px;
  22. border:1px solid black;
  23. cellspacing:1px;
  24. text-align:center;
  25. border-collapse:collapse;
  26. }
  27. caption{
  28. font-size:25px;
  29. margin:5px 0;
  30. }
  31. tr,td{
  32. border:1px solid black;
  33. padding:5px;
  34. }
  35. </style>';

再来一个controller脚本,里面就要用到服务容器类

  1. <?php
  2. namespace test;
  3. use Closure;
  4. //导入模型数据
  5. require 'model.php';
  6. //导入视图
  7. require 'view.php';
  8. class Container
  9. {
  10. //创建一个空数据来接受所有的类对象
  11. private $package = [];
  12. //创建一个方法,用来传递类闭包对象
  13. public function bind(string $type, \Closure $Closure)
  14. {
  15. $this->package[$type] = $Closure;
  16. }
  17. //提取需要使用的对象
  18. public function take(string $type, $params = [])
  19. {
  20. return call_user_func_array($this->package[$type], $params);
  21. }
  22. }
  23. //创建容器类实例
  24. $container = new Container;
  25. //把model与view传递进容器
  26. $container->bind('model', function () {
  27. return new Model;
  28. });
  29. $container->bind('view', function () {
  30. return new View;
  31. });
  32. // 调式
  33. // $model = $container->take('model');
  34. // $data = $model->getData();
  35. // $view = $container->take('view');
  36. // echo $view->fetch($data);
  37. // die;
  38. //门面类
  39. class Facade
  40. {
  41. private static $container;
  42. private static $data;
  43. //这里需要传入容器类实例
  44. public static function getMold(Container $container)
  45. {
  46. static::$container = $container;
  47. }
  48. public static function getData()
  49. {
  50. //这里步骤就是
  51. // $model = $container->take('model');
  52. // $data = $model->getData();
  53. static::$data = static::$container->take('model')->getData();
  54. }
  55. public static function fetch()
  56. {
  57. // 这里的步骤流程
  58. // $view = $container->take('view');
  59. // $view->fetch($data);
  60. return static::$container->take('view')->fetch(static::$data);
  61. }
  62. }
  63. //控制器
  64. class Controller
  65. {
  66. //这里的构造方法是为了给Facade类传递参数
  67. public function __construct(Container $container)
  68. {
  69. Facade::getMold($container);
  70. }
  71. public function fetch()
  72. {
  73. //获取model数据
  74. Facade::getData();view
  75. //获取view数据
  76. //这里需要注意,不要把return忘记了,不然没有内容输出
  77. return Facade::fetch();
  78. }
  79. }
  80. //创建控制器类实例,并把容器类实例传递进去
  81. $controller = new controller($container);
  82. echo $controller->fetch();

最终输出结果

路由的简单应用

先了解要用到的一些函数与常量

$_SERVER['REQUEST_URI']:返回值为地址栏上除域名/主机名外的完整地址

  1. <?php
  2. echo 'REQUEST_URI==> ' . $_SERVER['REQUEST_URI'] . '<br>';



$_SERVER['QUERY_STRING']:返回值为地址栏上查询字符串,在脚本名后面以’?’开头的

  1. <?php
  2. echo 'QUERY_STRING==>'. $_SERVER['QUERY_STRING']. '<br>';



$_SERVER['PATH_INFO']:返回值为地址栏上脚本名与查询字符串之间的字符串

  1. <?php
  2. echo 'PATH_INFO==>' . $_SERVER['PATH_INFO'] . '<br>';



parse_str():将一个查询字符串解析为键值对,保存到一个关联数组中

  1. <?php
  2. $str = 'id=20&name=test';
  3. \parse_str($str,$arr);
  4. print_r($arr);



explode():去掉分隔符,并以分隔符为界限,赋值到一个索引数组中

  1. <?php
  2. $str ='a+b+c+d';
  3. $arr = explode('+',$str);
  4. echo '<pre>'. print_r($arr,true) .'</pre>';



array_values():参数为数组,取出数组的值,并以索引数组方式重新排列

  1. <?php
  2. $arr = ['id'=>2,'cid'=>3];
  3. $arr = array_values($arr);
  4. echo '<pre>'. print_r($arr,true) .'</pre>';


根据以上的函数与常量就可以实现一个简单的路由原理

  1. <?php
  2. namespace chapter;
  3. echo $_SERVER['REQUEST_URI'];
  4. echo '<hr>';
  5. //获取path信息,并转为数组
  6. $pathinfo = explode('/', $_SERVER['PATH_INFO']);
  7. //去除掉空键值的元素,并以索引数组重新排序
  8. $pathinfo = array_values(array_filter(($pathinfo)));
  9. //检测path数据是否更新
  10. echo '<pre>'.print_r($pathinfo,true).'</pre>';
  11. //拿到类名
  12. $test = __NAMESPACE__. '\\'. ucfirst($pathinfo['0']). 'User';
  13. //拿到方法名;
  14. $func = $pathinfo['1'];
  15. //获取查询字符串
  16. $querystring = $_SERVER['QUERY_STRING'];
  17. \parse_str($querystring,$params);
  18. //测试
  19. echo '<pre>'.print_r($params,true).'</pre>';
  20. class TestUser
  21. {
  22. public function getUser($id,$name)
  23. {
  24. return 'id==>'. $id .': name==>'. $name;
  25. }
  26. }
  27. // 创建类实例
  28. $testuser = new $test;
  29. //因为类方法里面有id与name两个参数要传递
  30. //所以要使用call_user_func_array回调函数,里面第一个参数为数组,第一个表示类名,第二个表示类方法,第二个参数为需要传递的值,它必须为数组
  31. echo call_user_func_array([$testuser,$func],$params);

终于要把PHP赶完了,不知道最后的作业能完成不- -###加油,努力。。。

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