我知道如何解释这一点的最佳方式是使用示例,因此这里是我自己的 PHP-MVC 应用程序实现示例。请务必密切注意 Hook::run 函数,该函数处理加载控件的参数。
index.php:
<?php
class Hook {
const default_controller = 'home';
const default_method = 'main';
const system_dir = 'system/';
static function control ($name, $method, $parameter) {
self::req(Hook::system_dir.$name.'.php'); // Include the control file
if (method_exists('Control', $method)) { // For my implementation, I can all control classes "Control" since we should only have one at a time
if (method_exists('Control', 'autoload')) call_user_func(array('Control', 'autoload')); // This is extremely useful for having a function to execute everytime a particular control is loaded
return call_user_func(array('Control', $method), $parameter); // Our page is actually a method
}
throw new NotFound($_GET['arg']); // Appear page.com/control/method does not exist, so give a 404
}
static function param ($str, $limit = NULL) { // Just a wrapper for a common explode function
return (
$limit
? explode('/', rtrim($str, '/'), $limit)
: explode('/', rtrim($str, '/'))
);
}
static function req ($path) { // Helper class to require/include a file
if (is_readable($path)) return require_once($path); // Make sure it exists
throw new NotFound($path); // Throw our 404 exeception if it doesn't
}
static function run() {
list($name, $method, $parameter) = ( // This implementaion expects up to three arguements
isset($_GET['arg'])
? self::param($_GET['arg'], 3) + array(self::default_controller, self::default_method, NULL) // + array allows to set for default params
: array(self::default_controller, self::default_method, NULL) // simply use default params
);
return self::control($name, $method, $parameter); // Out control loader
}
}
class AuthFail extends Exception {}
class UnexpectedError extends Exception {}
class NotFound extends Exception {}
try {
Hook::run();
}
catch (AuthFail $exception) { // Makes it posssible to throw an exception when the user needs to login
// Put login page here
die('Auth failed');
}
catch (UnexpectedError $exception) { // Easy way out for error handling
// Put error page here
die('Error page');
}
catch (NotFound $exception) { // Throw when you can't load a control or give an appearance of 404
die('404 not found');
}
系统/home.php:
<?php
class Control {
private function __construct () {}
static function autoload () { // Executed every time home is loaded
echo "<pre>Home autoload\n";
}
static function main ($param='') { // This is our page
// Extra parameters may be delimited with slashes
echo "Home main, params: ".$param;
}
static function other ($param='') { // Another page
echo "Home other, params:\n";
$param = Hook::param($param);
print_r($param);
}
}
.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?arg=$1 [QSA,L]
通过这个 htaccess 文件,我们可以使用localhost/home/main 加载 home.php 控件。没有它,我们的网址看起来像localhost/index?args=home/main。
演示截图1(localhost/simple_mvc/home/main/args1/args2/args3):
您并不总是知道特定的控制方法需要多少个参数,这就是为什么我认为最好传递一个由斜杠分隔的单个参数。如果控制方法需要多个参数,则可以使用提供的Hook::param 函数进行进一步评估。
演示截图2(localhost/simple_mvc/home/other/args1/args2/args3):
回答您的问题:
这里真正有助于回答您的问题的关键文件是.htaccess 文件,它将localhost/these/types/of/urls 透明地转换为localhost/index.php?args=these/types/of/urls 之类的东西。然后,您可以使用 explode($_GET['args'], '/'); 拆分参数。
here 是关于此主题的精彩视频教程。这真的有助于解释很多。
我对 home.php 和 index.php 进行了一些修改,并进行了最新的编辑