веб-сервисы — Создание собственного средства разрешения аргументов для моей собственной структуры PHP

Я решил создать свою собственную мини — фреймворк для PHP, которую я собираюсь использовать для реальной работы, создание веб-службы для социального приложения.

Я начал с руководства Фабьена Потенсьера по созданию собственного фреймворка поверх компонентов Symfony — http://symfony.com/doc/current/create_framework/index.html.
Мне очень понравились его библиотеки classLoader и http-foundation и я решил их интегрировать.

Я прочитал весь учебник, но решил прекратить интеграцию компонентов Symfony до пятой части учебника, где он попадает в ядро ​​Symfony http, средство сопоставления маршрутов и преобразователь контроллеров (исключая таковые).

Есть вопрос о фронт-контроллере и картографическом маршруте моего фреймворка, о котором идет речь.

front.php (фронт-контроллер)

<?php

require 'config/config.php';
require 'config/routing.php';
require 'src/autoloader.php';

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$response = new Response();


$path = $request->getPathInfo();

if(isset($siteMap[$path])) {
call_user_func_array('src\Controllers' .'\\' . $siteMap[$path]['controller'] . '::' . $siteMap[$path]['action'], array($siteMap[$path]['arguments']));
} else {
$response->setStatusCode('404');
$response->setContent('Page not found');
}

$response->send();
?>

Мой файл маршрутизации:

/*
Map of routes
*/

$siteMap = array('/' => array('controller' => 'IndexController', 'action' => 'indexAction', 'arguments' => ''),
'/categories' => array('controller' => 'CategoriesController', 'action' => 'indexAction', '

То, что я хочу знать сейчас, без дальнейшего использования компонентов Symfony, как я могу сделать что-то вроде этого:

В моем файле маршрутизации я хочу добавить URL-адрес, например ‘/ hello’, с Controller — Hello Controller и именем аргумента, возрастом, полом, который будет соответствовать запросу в браузере GET www.base / hello / samuel / 11 / male.

А в HelloController есть indexAction ($ name, $ age, $ sex) {…}. Я попытался посмотреть на исходные тексты Symfony, но это ускользает от меня (я потратил много времени, изучая исходный код библиотек). Я собираюсь модульно разделить функции переднего контроллера и контроллера, решая их еще дальше, но я хочу разобраться в этом.

Да, и любые советы по дальнейшему построению моей инфраструктуры будут приветствоваться (я создаю инфраструктуру для REST-подобного веб-сервиса, который должен быть масштабируемым и быстрым и обрабатывать десятки тысяч запросов в секунду, возможно).

2

Решение

Вы должны определить регулярные выражения для своих маршрутов и сопоставить их с запросами, если вы хотите знать, как Symfony преобразует свой собственный формат маршрута, например: / path / to / {id} в регулярное выражение, см. RouteCompiler:: compilePattern. Это выходит за рамки этого вопроса, и я не предоставлю никакого кода для него.

Регулярное выражение для вашего примера маршрута будет что-то вроде ^/hello/(\w*)/(\d*)/(\w*)/$это будет соответствовать ‘/ привет / любая строка / любое число / любая строка /’, например: /hello/samuel/11/male (не забудьте ^ и $они соответствуют началу и концу строки).

Вы должны предоставить регулярное выражение для каждого маршрута и сделать preg_match(rawurldecode($request->getPathInfo(), $regex /* as created earlier*/, $matches) против всех маршрутов (до совпадения) вместо isset($sitemap[$path]) если это возвращает false, маршрут не совпадает. В противном случае вы должны получить аргументы для вашего контроллера следующим образом:

preg_match(rawurldecode($request->getPathInfo(), $regex /* as created earlier*/, $matches)
$args = array();
// we omit the first element of $matches, since it's the full string for the match
for($i = 1; $i < count($matches); $i++){
$args[] = $matches[$i];
}

Теперь вы можете объединить $args с аргументами по умолчанию и вызвать контроллер.


Увидеть UrlMatcher:: matchCollection () о том, как Symfony сопоставляет каждый маршрут с регулярным выражением и создает аргументы.

3

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

Я хотел бы добавить дополнительную информацию. В Symfony вы можете получить Аргументы вашего запроса в аргументы метода:

public function fooAction($bar);

В этом случае это будет выглядеть в $request->attributes за ключ с bar, если значение присутствует, оно добавит это значение в ваше действие. В Symfony 3.0 и ниже это делается через ControllerResolver::getArguments(). Начиная с Symfony 3.1 вы сможете реализовать или расширить ArgumentResolver.

Используя ArgumentResolver означает, что вы можете легко добавить свой собственный функционал в решение. Существующие преобразователи значений находятся здесь.

0

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