Как справиться меняется в PHP
У меня есть приложение, предположительно API, над которым я работаю. Приложение возвращает запрошенные ресурсы в формате JSON. Итак, у меня есть приложение для управления проектами, где структура похожа на то, что показано ниже:
- проекты
- платежи
- вопросы
- Обсуждение
- пользователи
Теперь API будет вызывать:
/projects List all the projects
/project List all the projects (alias)
/projects/ID/issues List all the issues of this project
/project/ID/issues List all the issues of this project (alias)
/projects/ID/issue List all the issues of this project (alias)
/project/ID/issue List all the issues of this project (alias)
И так далее. Теперь проблема для меня заключается в том, что я буду использовать switch ($request)
для это и у меня есть сумасшедшие case
утверждения, как показано ниже:
<?php
switch ($request) {
case '/projects':
case '/project':
# code...
break;
case '/projects/ID/issues':
case '/project/ID/issues':
case '/projects/ID/issue':
case '/project/ID/issue':
# code...
break;
}
Я надеюсь, что вы поняли проблему. Подумайте о количестве случаев для части discussion
. Было бы гораздо больше. Это будет идти по комбинации значений 3
, которые придут к 2
в силу 3
(23) что приходит в голову 8
case
заявления.
3 ответа:
Вы можете уменьшить его, проверив с первой попытки. то есть, проверьте наличие множественного или единственного числа и замените его одной единственной формой.
<?php $request = replace(array("projects", "project"), "project", $request); $request = replace(array("issues", "issue"), "issue", $request); $request = replace(array("users", "user"), "user", $request); $request = replace(array("discussions", "discussion"), "discussion", $request);
И позже проверьте в случае
switch ()
только единственную форму:Я знаю, что это будет повторяющаяся задача, но я думаю, что если вы не хотите использовать какие-либо методы плюрализации, это лучше. Надеюсь, что этот "быстрый хак" будет полезен. Поскольку у вас не более трех-четырех переменных, это лучше.<?php switch ($request) { case '/project': # code... break; case '/project/ID/issue': # code... break; }
Примечание: основная причина, по которой я дал этот ответ, - это простота и отсутствие использования регулярных выражений.
Определение маршрутов
Я бы рекомендовал использовать
preg_match
для такого рода вещей. Начните с создания массива с именами маршрутов в качестве ключей и регулярными выражениями в качестве значений:$routes = [ 'projects' => '/\/projects?$/', 'payments' => '/\/projects?\/([0-9]+)\/payments?$/', 'issues' => '/\/projects?\/([0-9]+)\/issues?$/', 'discussions' => '/\/projects?\/([0-9]+)\/issues?\/([0-9]+)\/discussions?$/', 'users' => '/\/users?$/ ];
Теперь проверьте, какой маршрут соответствует вашему url:
function getRoute($url, $routes) { foreach ($routes as $name => $regex) { if (preg_match($regex, $url)) { return $name; } } // return false, or throw an exception if no route has been found }
И теперь вы можете просто перейти по названию маршрута в вашем коммутаторе:
Я считаю, что это самое элегантное решение для того, что вы пытаетесь сделать. При желании массив маршрутов можно легко экспортировать во внешнюю конфигурацию. И Вы тоже избегая любых изменений url.switch (getRoute($request, $routes)) { case 'projects': ... case 'payments': ... case 'issues': ... case 'discussions': ... case 'users': ... }
Выборка параметров (идентификаторов)
Вы можете развернуть функцию
getRoute
, Чтобы не только вернуть имя маршрута, но и вернуть параметры:function getRoute($url, $routes) { foreach ($routes as $name => $regex) { if (preg_match($regex, $url, $matches) { // removes the first match which is the whole url array_shift($matches); return ['route' => $name, 'params' => $matches]; } } }
Выше будет возвращен массив, содержащий совпадающее имя маршрута, а также его параметры. Вот пример:
$route = getRoute('/project/13/issues/14/discussions', $routes); // $route = [ // 'route' => 'discussions', // 'params' => [0 => '13', 1 => '14'] // ];
Просто не забудьте изменить оператор switch на:
Дайте мне знать, если вам понадобятся дальнейшие объяснения.$route = getRoute($request, $routes); switch($route['route']) { ... }
Аналогичный подход к Praveen Kumars заключается в разборе запроса по частям и обработке их соответствующим образом. Вы можете разделить его с помощью
$requestParts = explode('/',$request);
, затем вы идете:if (($requestParts[0]=='project')||($requestParts[0]=='projects')) { handleProjectRequest($requestParts); } elseif (($requestParts[0]=='user')||($requestParts[0]=='users')) { handleUserRequest($requestParts); } //...and so on...
Ваши подфункции могут выглядеть следующим образом:
Это поможет вам избавиться от этого гигантского оператораfunction handleProjectRequest(&$requestParts) { if ($requestParts[1]=='ID') { //seems to be the only case? if (($requestParts[2]=='issue')||($requestParts[2]=='issues')) { //do your magic } } }
switch
, а также довольно хорошо организовать ваш код.В расширенном виде вы можете определить формы множественного и единственного числа для каждого случая в массиве, например:
$projectRequests=['project,projects'];
и проверить их позже.:Преимущество этого подхода состоит в том, что вы можете централизованно определить все возможные части каждого запроса.if (in_array($requestParts[0],$projectRequests)) { handleProjectRequest($requestParts); }