Название немного вводит в заблуждение. Позвольте мне объяснить лучше на примере:
Предположим, что у меня есть такой URI: localhost/api/user/method/5
,
URI состоит из:
[0]
=> локальный: базовый путь к серверу
[1]
=> апи: базовый путь к приложению
[2]
=> пользователь: представляет пользовательский контроллер
[3]
=> GetUser: представляет метод getUser
[4]
=> 5: это параметр
что я хочу сделать, это создать экземпляр класса User
доступны в user.php
файловый контроллер, вызов функции getUser
доступны в user
контроллер и передать параметр 5
, Так должно быть что-то вроде (пример кода):
$Class = ucfirst("user");
// create an instance
$ctr = new $Class();
// and call the requested function
$ctr->$func(); //$func should be valorized with getUser in this case
Теперь я создал класс, который является простым router
система.
<?php
class Route
{
/**
* @var array $_listUri List of URI's to match against
*/
private $_listUri = array();
/**
* @var array $_listCall List of closures to call
*/
private $_listCall = array();
/**
* @var string $_trim Class-wide items to clean
*/
private $_trim = '/\^$';
/**
* add - Adds a URI and Function to the two lists
*
* @param string $uri A path such as about/system
* @param object $function An anonymous function
*/
public function add($uri, $function)
{
$uri = trim($uri, $this->_trim);
$this->_listUri[] = $uri;
$this->_listCall[] = $function;
}
// submit - Looks for a match for the URI and runs the related function
public function submit()
{
$uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
$uri = trim($uri, $this->_trim);
$replacementValues = array();
// List through the stored URI's
foreach ($this->_listUri as $listKey => $listUri)
{
// See if there is a match
if (preg_match("#^$listUri$#", $uri))
{
//Replace the values
$realUri = explode('/', $uri);
$fakeUri = explode('/', $listUri);
// Gather the .+ values with the real values in the URI
foreach ($fakeUri as $key => $value)
{
if ($value == '.+')
{
$replacementValues[] = $realUri[$key];
}
}
// Pass an array for arguments
call_user_func_array($this->_listCall[$listKey], $replacementValues);
}
}
}
}
что я хочу достичь, это взять базовый путь URL [2] => user
и сохранить его как контроллер, [3] index
следует использовать как функцию, указанную на контроллере, а [4] index
должен быть параметр, обратите внимание, что: [4] index
может быть необязательным параметром. На самом деле класс просто работает следующим образом:
$route->add('/user/.+', function($name) {
echo "Name $name";
});
$route->submit();
так что если пользователь вставит этот URI в браузер:
localhost/api/user/5
будет напечатано:
Имя 5
Как я могу реализовать логику, описанную выше?
ОБНОВЛЕНИЕ — вызов функции с некоторыми параметрами
$controller = $realUri[0]; 'Contains the controller to load
$func = $this->_listCall[$listKey]; 'contains the function to load
include dirname(dirname(__DIR__)) . "/application/controllers/" .
$controller . ".php" ;
$Class = ucfirst($controller);
$ctr = new $Class();
//$ctr->$func($replacementValues);
переменная $replacementValues
это так:
array(2) { [0]=> string(1) "5" [1]=> string(1) "9" }
и содержит все параметры, переданные в URL:
localhost/api/user/method/5/9
так как я могу передать весь этот параметр в функцию $func()
?
$url = "http://localhost:80/api/user/method/5";
$parsedUrl = parse_url($url);
var_dump($parsedUrl);
Будет печатать
array(4) {
["scheme"]=>
string(4) "http"["host"]=>
string(9) "localhost"["port"]=>
int(80)
["path"]=>
string(18) "/api/user/method/5"}
Теперь довольно просто разложить ваш путь так, как вы хотите:
if (!empty($parsedUrl['path'])) {
$patg = explode('/',$parsedUrl['path']);
}
Других решений пока нет …