Передний контроллер лучший способ связать параметры с логикой приложения?

Я создаю приложение, используя шаблон проектирования Front Controller, и есть только одна страница index.php через который все пользовательские запросы передаются в качестве параметров (в отличие от разных страниц / контроллеров в обычном дизайне).

Как я могу подключить эти параметры к логике приложения?

например У меня есть два разных действия:

index.php?action=userLogin&username=admin&password=qwerty //process user login

index.php?action=displayUsersTable //show registered users

В настоящее время у меня есть array со всеми действиями, которые принимает система (вместе с ожидаемыми аргументами), и я сравниваю action параметр от URL до key этого массива, а затем проверьте необходимые аргументы для этого действия.

//1 = optional, 2=required
$systemActions = [
"userLogin" => [
"login" => 2,
"password" => 2
],
"displayUsersTable" => []
];

Очевидно, что это станет массивом монстров по мере роста системы.

Есть ли лучший подход для привязки параметров, отправляемых на фронт-контроллер, к действиям системы?

10

Решение

Поскольку код «исправлен» (т.е. не извлекается из базы данных), то нет необходимости перекачивать в массив (и все накладные расходы на обработку / память, которые ему требуются. Так что да, его можно улучшить.

Но есть много вариантов в зависимости от того, насколько вырастет проект.

самый простой

Самым простым будет простое выражение «если» или переключатель. Я бы начал там, чтобы все было просто.

Более сложный

Вы говорите, что другие проекты имеют разные страницы / контроллеры — но есть причина. И поскольку вы просите об улучшениях, особенно если вы ожидаете, что проект будет расти до такой степени, в которой вы будете искать оптимизацию, тогда вам действительно следует учитывать эти причины (и разбивать их на файлы).

На другом конце шкалы вы можете разделить все вызовы на файлы / классы и автоматически загрузить файлы / классы.

Таким образом, вы выполняете только необходимый вам код (файлы меньшего размера), он очень модульный и с ним легко работать совместно. И если вы добавляете новое действие, вам не нужно изменять индекс или массив — вы только изменяете файл действия, над которым работаете.

пример (значительно упрощено из проекта, над которым я сейчас работаю с этим подходом):

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) Создайте классы «action», расширив базовый Action. Сохраните их в отдельных файлах (чтобы другие могли сотрудничать в проекте без вмешательства).

// put in 'actions/userLogin.php
class userLogin extends baseAction {
protected $aExpectedParams = [
'login' => ['type' => 'string', 'required' => true]
'password' => ['type' => 'string', 'required' => true]  // NOTE: you should never actually pass password unencrypted through "get" as they'll get stuck in user logs!
];

public function execute() {
// Do Whatever
}
}

.

// put in 'actions/displayUsersTable.php
class displayUsersTable extends baseAction {
public function execute() {
// Do Whatever
}
}

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» — проверка того, что кто-то еще не запрашивал общий класс php, такой как «object»; если вы в большей безопасности, вам следует указать это или добавить дополнительную проверку. Это всего лишь пример!)

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]