你会想要构建一个基本的路由器,它是做什么的。
路由器将解析路径并获取其中的一部分并定位控制器文件。然后在该文件中运行带有参数的方法。我们将使用这种格式的网址
www.yoursite.com/index.php/{controller}/{method}/{args}
所以对于这个例子,我们的 url 将是
www.yoursite.com/index.php/home/index/hello/world
index.php 可以使用一些基本的 .htaccess (Mod Rewrite) 隐藏
所以让我们定义一些东西,首先我们将有文件夹
-public_html
index.php
--app
---controller
home.php
所以主文件夹是public_html,其中index.php 和一个名为app 的文件夹。在app 里面是一个名为controller 的文件夹,里面是我们的home.php 控制器
现在是代码(是的)
index.php(基本路由器)
<?php
//GET URI segment from server, everything after index.php ( defaults to home )
$path_info = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : '/home';
//explode into an array - array_filter removes empty items such as this would cause '/home//index/' leading /, trailing / and // double slashes.
$args = array_filter( explode('/', $path_info) );
$controller_class = array_shift($args); //remove first item ( contoller )
$method = count( $args ) > 0 ? array_shift($args) : 'index'; //remove second item or default to index ( method )
$basepath = __DIR__.'/app/controller/'; //base path to controllers
if(!file_exists($basepath.$controller_class.".php") ){
echo "SHOW 404";
exit();
}
//instantiate controller class
require_once $basepath.$controller_class.".php";
$Controller = new $controller_class;
//check if method exists in controller
if(!method_exists( $Controller, $method ) ){
echo "Method not found in controller / or 404";
exit();
}
//call methods with any remaining args
call_user_func_array( [$Controller, $method], $args);
home.php(控制器)
<?php
class home{
public function index( $arg1="", $arg2=""){
echo "Arg1: ".$arg1 . "\n";
echo "Arg2: ".$arg2 . "\n";
}
public function test( $arg1 = "" ){
echo "Arg1: ".$arg1 . "\n";
}
}
现在,如果您输入这些网址中的任何一个
www.yoursite.com/index.php
www.yoursite.com/index.php/home
www.yoursite.com/index.php/home/index
它应该打印(默认)
Arg1:
Arg2:
如果你做这个网址
www.yoursite.com/index.php/home/index/hello/world
应该打印出来
Arg1: hello
Arg2: world
如果你这样做了
www.yoursite.com/index.php/home/test/hello_world
它会打印出来
Arg1: hello_world
最后一个,在第二个方法test(没有echo arg2)中运行,这样你可以看到我们如何添加更多的控制器和方法,只需将它们编码到一个控制器中。
此方法仍然允许您使用 url 的 $_GET 部分以及 URI 部分将信息传递给控制器。所以这仍然有效
www.yoursite.com/index.php/home/test/hello_world?a=1
并且您可以(在 home::test() 中)毫无问题地输出 $_GET 的内容,这对于搜索表单等很有用。一些漂亮的 url 方法可以防止这种情况,这只是......好吧......废话。
在 .htaccess 中使用 mod rewrite 您可以这样做以从 url 中删除 index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
然后你可以使用不带index.php的url比如这个
www.yoursite.com/home/index/hello/world
这是我能在这么短的时间内想到的最简单的路由器,是的,我刚刚创建了它。但这与许多 MVC 框架中使用的非常相似(尽管是简化的)实现
PS。请理解这一切是如何完成的,所以你实际上学到了一些东西......
可以进行许多改进,例如允许这些网址
www.yoursite.com/hello/world
www.yoursite.com/home/hello/world
www.yoursite.com/index/hello/world
这将全部退回到家庭控制器和索引方法的默认值,但这需要一些额外的检查(对于未找到的文件和方法)我现在不能打扰......