带数组的路由系统 - 带变量的发送参数

时间:2017-06-04 21:00:58

标签: php arrays regex model-view-controller routing

我尝试用PHP构建路由系统。我的可更改网址存在问题。

private $routes = array(
    "blog" => array("Blog", "GetAll"),
    "/blog\/*/" => array("Blog", "GetOne"),
);

private $query;

public function __construct()
{
    $this->query = filter_var($_SERVER['QUERY_STRING'], FILTER_SANITIZE_URL);
}

public function SendAction()
{
    $route = array();
    if (array_key_exists($this->query, $this->routes)) {
        $route['controller'] = $this->routes[$this->query][0];
        $route['action'] = $this->routes[$this->query][1];
        $route['params'] = $this->routes[$this->query][2];
    } else {
        $route['controller'] = "Error";
        $route['action'] = "Main";
        $route['params'] = array();
    }
    return $route;
}

问题在于包含abc/my_custom_variable_or/slug的网址。

我需要获取my_custom_variable_orslug并将它们放入params['fdsaf'],以便我可以在我的控制器中使用它

我找到了一个带有else的临时解决方案,如:else if (preg_match("/blog\/*/", $this->query)) .... explode()等......

为了使我的系统更灵活,我需要在$routes数组中创建一些东西。 routes数组将是一个不同的文件。

===样本输入和预期结果===

网址:博客

$route['controller'] = Blog
$route['action'] = GetAll
$route['params'] = array()

网址:博客/我的第一篇文章

$route['controller'] = Blog
$route['action'] = GetOne
$route['params'] = array('slug' => 'my-first-post')

网址:blog / user / martin / page2(第2页是可选的)

$route['controller'] = Blog
$route['action'] = GetUserPost
$route['params'] = array('slug' => 'martin')

1 个答案:

答案 0 :(得分:0)

我的正则表达式模式将捕获3组。第一个是前导文本 - 对于所有三个样本输入,这是blog。第二组将为空或user - 这标识何时使用GetUserPost。第三组可能为空或包含slug值。

Pattern Demo

代码(PHP Demo):

if(preg_match('/^([^\/]+)\/?((?:user)?)\/?((?:[^\/]+)?)/',$v,$out)){
    $route['controller']=ucfirst($out[1]);
    if($out[2]==''){
        if($out[3]==''){
            $route['action']='GetAll';
            $route['params']=[];
        }else{
            $route['action']='GetOne';
            $route['params']=['slug'=>$out[3]];
        }
    }else{
        $route['action']='GetUserPost';
        $route['params']=['slug'=>$out[3]];
    }
}

硬编码Blog版本:

$inputs=['blog','blog/my-first-post','blog/user/martin/page2'];
foreach($inputs as $v){
    $route=[];
    if(preg_match('/^[^\/]+\/?((?:user)?)\/?((?:[^\/]+)?)/',$v,$out)){
        $route['controller']='Blog';
        if($out[1]==''){
            if($out[2]==''){
                $route['action']='GetAll';
                $route['params']=[];
            }else{
                $route['action']='GetOne';
                $route['params']=['slug'=>$out[2]];
            }
        }else{
            $route['action']='GetUserPost';
            $route['params']=['slug'=>$out[2]];
        }
    }
    var_export($route);
}

输出(来自任一方法):

array (
  'controller' => 'Blog',
  'action' => 'GetAll',
  'params' => 
  array (
  ),
)array (
  'controller' => 'Blog',
  'action' => 'GetOne',
  'params' => 
  array (
    'slug' => 'my-first-post',
  ),
)array (
  'controller' => 'Blog',
  'action' => 'GetUserPost',
  'params' => 
  array (
    'slug' => 'martin',
  ),
)