gpt4 book ai didi

php - 创建一个 PHP 'controller' 文件来构建站点上的所有页面

转载 作者:行者123 更新时间:2023-12-04 04:55:15 27 4
gpt4 key购买 nike

我正在使用 CodeIgniter 框架开发另一个项目,该框架有一个主 Controller 文件,用于构建网站上的所有页面。

输入诸如“domain.com/about”之类的 url 将在 Controller 文件中运行“function about(){”,该文件加载到该页面的各个组件中。

这其中的大部分魔法都是由 CodeIgniter 或其他项目成员处理的,所以我不确定这是如何发生的。

我希望在不使用任何框架的情况下实现相同的目标,并且完全不知道如何完成它。我知道我可以在“domain.com?load=about”的某处有一个 url,并使用它来运行该功能,但我希望该 URL 干净,便于访问者访问输入。

所以,我的问题是..如何设置我的网站,使其始终指向单个文件“controller.php”,然后运行一个与 URL 中输入的内容匹配的函数,并且该 URL 不是直接的我远离 Controller 页面? (也就是说,如果我输入 'domain.com/about' 我不想被带到 about.php 页面!)

如果这个问题难以理解,或者我对任何事情采取了错误的方法,我提前道歉。也因为缺乏例子和描述..我真的不知道更具体。如果您有什么需要看或知道的,尽管问,我会尽力澄清!

谢谢!

最佳答案

您对此没有很多好的答案。让我们添加更多细节。

CodeIgniter 的工作原理

网址路由

CodeIgniter 的第一步实际上是在 CodeIgniter 本身之外完成的。您将在 HTTP 守护程序中找到此步骤。如果是 Apache,你会看到类似这样的重写规则:

  RewriteRule ^(.+)$ /index.php?$1 [L]

如果你正在运行 nginx,你会看到:
  rewrite ^/(.+)$ /index.php?/$1 last;

这是每个框架的核心指令之一,将导致它处理和解析每个请求(根据 RewriteCond/ try_files 指令,可能包含找到或未找到的文件)。用户提供的查询字符串将在 $_SERVER['QUERY_STRING'] 中可用.请记住这一点,我们将不止一次地回到这一点。

进入框架

如果您计划构建一个框架,您的框架应该具有称为 的功能。路由器 .这是一个简洁的小类(或类集合),它将处理 的动态创建。路线 .路由是 URI(可能包含通配符)和 Controller 功能(或多个功能)之间的定向映射。

第一次编写自己的框架的人经常忽略这一点,并且可以在有效的东西和使用起来非常痛苦的东西之间产生差异(PHP 的差异很小。这在其他技术上确实很明显)。

所以。一个路由器。获取路线列表,将它们转换为类和函数。我们想要缓存我们的 Controller 并提供它们的动态分配,所以我们将带来一个新概念: 控制反转 .如果您使用过更新的框架(Kohona、Laravel 等),您会对此很熟悉。实际上,它允许您将类名绑定(bind)到 go-to 字符串并通过中介控制此类类的实例化(从而遵循好莱坞原则 - 您请求 Controller ,您不实例化它)。

经典的 IoC 包装器如下所示:
 class IoC {
private static $cache = array();
private static $singletons = array();
public static function register($name,$className,$isSingleton=false) {
if (!isset(self::$cache[$name])) {
self::$cache[$name] = array("class" => $className, "singleton" => !!$isSingleton);
}
}
public static function instance($name) {
if (!isset(self::$cache[$name])) throw new Exception("Class not found in IoC container");
$cN = self::$cache[$name]['class'];
if (!empty(self::$cache[$name]['singleton'])) {
if (!isset(self::$singletons[$cN])) {
self::$singletons[$cN] = new $cN();
}
return self::$singletons[$cN];
}
else {
return new $cN();
}
}
}

这有很多好处:
  • 您很可能有一天会决定将您的 Controller 更改为 Controller2来自 Controller1 .通过使用 IoC wrapper 来解决它,您可以省去一些痛苦 - 不必遍历整个代码
  • Handlebars Singletons原生而不会使它们难以进行单元测试

  • 所以。凭借我们的知识,我们现在可以使用 IoC::instance("ourkeyword"); 根据我们选择的任意关键字实例化一个类。 .我们将一点一点地使用它。首先,一个警告: 此 IoC 包装器假定您将使用 spl_autoload 延迟加载您的类 .

    路由器本身将类似于以下内容:
     class Router {
    public $routes = array();
    public function register($route, $controller, $method, $request_type=7) {
    $this->routes[] = array("route" => $route, "call" => array($controller, $method), "request_type" => 7);
    }
    public function route($str) {
    foreach ($this->routes as $v) {
    // Do your request_type match here. Exercise left for the reader!
    if (preg_match($str, $v['route'], $matches)) {
    try {
    $controller = IoC::instance($v['call'][0]);
    if (!method_exists($controller, $v['call'][1])) throw new Exception("Method not found: ".$v['call'][1]);
    array_shift($matches);
    call_user_func_array(array($controller,$v['call'][1]), $matches);
    } catch (Exception $e) {
    }
    }
    }
    }
    }

    那是你的路由器!您可能想知道为什么 IoC是纯静态类, Router被实例化。原因很简单:您可能希望您的模块拥有自己的子路由器,而不必总是处理一个路由器。我经常这样做,这使我能够完全划分我的 PAC 结构并构建逻辑路由层次结构。

    这就是所有的路由!从前面看,您的框架代码现在看起来像:
      IoC::register("controller1","My\\Controller");
    $router = new Router();
    $router->register(...);
    $router->route($_SERVER['QUERY_STRING']);

    很好,整洁,抽象了所有的问题!由此,您可以构建您的框架以遵循 MVC 架构或其任何变体。这与 PAC 一起工作得非常好。

    关于php - 创建一个 PHP 'controller' 文件来构建站点上的所有页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16843004/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com