Php 前端控制器将参数链接到应用程序逻辑的最佳方式?
我正在使用Front Controller设计模式构建一个应用程序,其中只有一个页面Php 前端控制器将参数链接到应用程序逻辑的最佳方式?,php,front-controller,Php,Front Controller,我正在使用Front Controller设计模式构建一个应用程序,其中只有一个页面index.php,所有用户请求都作为参数传递(与常规设计中的不同页面/控制器相比) 如何将这些参数连接到应用程序逻辑 e、 g.我有两种不同的行为: index.php?action=userLogin&username=admin&password=qwerty //process user login index.php?action=displayUsersTable //show re
index.php
,所有用户请求都作为参数传递(与常规设计中的不同页面/控制器相比)
如何将这些参数连接到应用程序逻辑
e、 g.我有两种不同的行为:
index.php?action=userLogin&username=admin&password=qwerty //process user login
index.php?action=displayUsersTable //show registered users
目前,我有一个数组
,包含系统接受的所有操作(以及预期参数),我将操作
参数从URL比较到此数组的键
,然后检查此操作所需的参数
//1 = optional, 2=required
$systemActions = [
"userLogin" => [
"login" => 2,
"password" => 2
],
"displayUsersTable" => []
];
显然,随着系统的发展,这将成为一个怪物阵列
是否有更好的方法将发送到前端控制器的参数绑定到系统操作?由于代码是“固定的”(即不是从数据库驱动的),因此无需注入阵列(以及它所需的所有处理/内存开销)。因此,是的,它可以得到改进
但根据项目的发展程度,有很多选择
最简单的
最简单的是简单的“if”语句,或者一个开关。我从这里开始让它保持简单
更复杂
<>你说其他项目有不同的页面/控制器-但是有一个原因。当你要求改进时,特别是如果你期望项目增长到你正在寻找优化的程度,那么你真的应该考虑这些原因(并分成文件)。
在刻度的另一端,您可以将所有调用拆分为文件/类,并自动加载文件/类
这样,您只需执行所需的代码(较小的文件大小),这是非常模块化的,并且易于协同工作。而且,如果您添加了新操作,则无需修改索引或数组,您只需修改正在处理的操作文件
示例(从我目前使用此方法进行的项目中大大简化):
1) 创建一个“baseAction”基类,所有操作都将从中扩展。您可以添加常见功能,如清理/预处理参数、日志记录、验证标头等
abstract class baseAction {
protected $aExpectedParams = [];
protected $aParams = [];
protected $validParams = true;
function __construct() {
foreach (self::$aExpectedParams as $name=>$aParam) {
if (isset($_GET[$name]))
if ($aParam['type'] == 'string') {
self::$aParams[$name] = $_GET[$name];
} elseif ($aParam['type'] == 'int') {
self::$aParams[$name] = (int)$_GET[$name];
}
} elseif ($aParam['required']) {
self::$validParams = false;
}
}
}
// This is the called function
abstract function execute();
}
2) 通过扩展基本动作来创建“动作”类。将它们保存在单个文件中(以便其他人可以在不干扰的情况下就项目进行协作)
3) 创建一个自动加载器以拉入这些单独的文件
function myAutoloader($className) {
if (file_exists(__DIR__ . '/actions/' . $className . '.php')) {
require_once(__DIR__ . '/actions/' . $className . '.php');
}
}
spl_autoload_register ('myAutoloader');
4) 那么您的index.php就像
$action = $_GET['action'] ?? '';
if (strlen($action) > 0 && class_exists($action) && method_exists($action, 'execute')) {
$oAction = new $action();
$oAction->execute();
} else {
// Oopsie
}
(最后一个代码段的注释:“class_exists”触发自动加载器。“method_exists”用于检查是否有人请求了诸如“object”之类的普通php类;如果您更安全,则应该为其命名名称空间或添加额外的验证。这只是一个示例!)
function myAutoloader($className) {
if (file_exists(__DIR__ . '/actions/' . $className . '.php')) {
require_once(__DIR__ . '/actions/' . $className . '.php');
}
}
spl_autoload_register ('myAutoloader');
$action = $_GET['action'] ?? '';
if (strlen($action) > 0 && class_exists($action) && method_exists($action, 'execute')) {
$oAction = new $action();
$oAction->execute();
} else {
// Oopsie
}