PHP实现的简单路由和类自动加载功能

这篇文章主要介绍了PHP实现的简单路由和类自动加载功能,结合实例形式分析了php路由及类自动加载的原理与相关实现技巧,需要的朋友可以参考下。

本文实例讲述了PHP实现的简单路由和类自动加载功能,分享给大家供大家参考,具体如下:

项目目录如下

入口文件index.php

  1. <?php
  2. define('WEBROOT', 'C:/Users/Administrator/Documents/NetBeansProjects/test');
  3. require_once(WEBROOT.'/core/environment.php');
  4. core__app::run(); //

类自动加载文件environment.php

  1. <?php
  2. //根据类名来include文件
  3. class loader {
  4. //找到对应文件就include
  5. static function load($name) {
  6. $file = self::filepath($name);
  7. if ($file) {
  8. return include $file;
  9. }
  10. }
  11. static function filepath($name, $ext = '.php') {
  12. if (!$ext) {
  13. $ext = '.php';
  14. }
  15. $file = str_replace('__', '/', $name) . $ext; //类名转路径
  16. $path .= WEBROOT . '/' . $file;
  17. if (file_exists($path)) {
  18. return $path; //找到就返回
  19. }
  20. return null;
  21. }
  22. }
  23. spl_autoload_register('loader::load');

我这里类的加载规则是 比如core__app::run() 对应 根目录/core/app.php 的 run()方法,用到了spl_autoload_register()函数实现自动加载,当调用某个类名的时候,会自动执行spl_autoload_register('loader::load'),根据类名include对应的类文件。

app.php入口文件执行的方法开始跑框架流程

  1. <?php
  2. class core__app {
  3. static function run() {
  4. $a = $_SERVER['REQUEST_URI'];
  5. $uri = rtrim(preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']), '/');
  6. $params = explode('/', trim($uri, '/'));
  7. $count = count($params);
  8. if ($count > 1) {
  9. $controller = $params[0];
  10. $method = $params[1];
  11. } elseif ($count == 1) {
  12. $controller = 'index';
  13. $method = $params[0];
  14. } else {
  15. }
  16. $filename = WEBROOT . '/controller/' . $controller . '.php';
  17. $controller = 'controller__'.$controller;
  18. try {
  19. if (!file_exists($filename)) {
  20. throw new Exception('controller ' . $controller . ' is not exists!');
  21. return;
  22. }
  23. include($filename);
  24. if (!class_exists($controller)) {
  25. throw new Exception('class ' . $controller . ' is not exists');
  26. return;
  27. }
  28. $obj = new ReflectionClass($controller);
  29. if (!$obj->hasMethod($method)) {
  30. throw new Exception('method ' . $method . ' is not exists');
  31. return;
  32. }
  33. } catch (Exception $e) {
  34. echo $e; //展示错误结果
  35. return;
  36. }
  37. $newObj = new $controller();
  38. call_user_func_array(array($newObj, $method), $params);
  39. }
  40. }

根据请求uri去找对应的controller, 用call_user_func_array()的方式调用controller里的方法

根目录/controller/test.php

  1. <?php
  2. class controller__test {
  3. public function write($controller, $method) {
  4. //config__test::load('test');
  5. model__test::write($controller, $method);
  6. }
  7. }

这里其实调用不一定要调用model里的test方法,可以调model目录下的任意文件,在此之前可以去都读一些config文件等等操作。

根目录/model/test.php

  1. <?php
  2. class model__test {
  3. public function write($model, $method) {
  4. echo 'From controller:'.$model.' to model: ' . $model . ' ,method: ' . $method;
  5. }
  6. }

例如hostname/test/write 这个请求就会从入口文件进来,经过core__app::run就会找到controller下对应的的controller__test类,执行write()方法。