如何建立PHP MVC的好路由器(how to build a good router for ph

2019-07-29 12:42发布

我用PHP MVC试验和我stucked有以下问题。 我的请求,路由器类是非常简单的,我谨向主题,可以处理来自子文件夹控制呼叫和控制器类的功能应该能够拿起URL变量把它扔GET和POST。

我的路由器看起来它遵循

class Router{

    public static function route(Request $request){


        $controller = $request->getController().'Controller';

        $method = $request->getMethod();

        $args = $request->getArgs();


        $controllerFile = __SITE_PATH.'/controllers/'.$controller.'.php';


        if(is_readable($controllerFile)){
            require_once $controllerFile;

            $controller = new $controller;


            if(!empty($args)){
                call_user_func_array(array($controller,$method),$args);
            }else{  
                call_user_func(array($controller,$method));
            }   
            return;
        }

        throw new Exception('404 - '.$request->getController().'--Controller not found');
    }
}

和Request类

  private $_controller; private $_method; private $_args; public function __construct(){ $parts = explode('/',$_SERVER['REQUEST_URI']); $this->_controller = ($c = array_shift($parts))? $c: 'index'; $this->_method = ($c = array_shift($parts))? $c: 'index'; $this->_args = (isset($parts[0])) ? $parts : array(); } public function getController(){ return $this->_controller; } public function getMethod(){ return $this->_method; } public function getArgs(){ return $this->_args; } } 

问题是:当我尝试发送扔阿贾克斯,变量的控制方法,这是不是因为它的URL结构的认可。 例如

index/ajax?mod_title=shop+marks&domain=example

如果它看起来只是接受

index/ajax/shop+mark/example

Answer 1:

你的代码中包含所谓的LFI漏洞 ,并在其当前状态的危险。
你应该列入白名单,你有什么可以作为你的$controller ,否则攻击者可以尝试使用NUL字节,可能会建立一个目录,包括不应该永远包含的文件,如指定的东西/etc/passwd ,一个配置文件,等等。

您的路由器是不是可以安全使用; 谨防!

编辑:例如在白名单

$safe = array(
    'ajax',
    'somecontroller',
    'foo',
    'bar',
);
if(!in_array($this->_controller, $safe))
{
    throw new Exception(); // replace me with your own error 404 stuff
}


Answer 2:

由于您的请求类使用识别控制器,动作和参数的URI段的方法,全局变量如$ _GET或$ _REQUEST不考虑从您的要求之内。

什么,你需要做的是做一些补充,你的请求代码。 特别:

删除行:

$this->_args = (isset($parts[0])) ? $parts : array();

并添加以下内容:

$all_parts = (isset($parts[0])) ? $parts : array();
$all_parts['get'] = $_GET;
$this->_args = $all_parts;

这样,$ _ GET(即变量通过URL传递变量)将在被称为可用的动作,因为他们将在的$ args(他们将作为的$ args [“得到”]实际上,这是一个包含数组在$ _GET瓦尔,这样你就可以拥有使用的$ args [“得到”] [“域”])访问域=例子。

Ofcourse,你可以在你的请求类(如查询)可能看起来像那增加一个方法:

public function query($var = null)
{
    if ($var === null)
    {
        return $_GET;
    }
    if ( ! isset($_GET[$var]) )
    {
        return FALSE;
    }
    return $_GET[$var];
}

这样一来,就可以从URL得到一个变量(例如$请求 - >查询(“域”))或整个$ _GET数组($请求 - >查询())。



Answer 3:

这是因为PHP将在放“?mod_title = ...” $_GET阵列自动。 你getArgs()函数应该检查$_GET$_POST$_REQUEST

如果你想为一个最小的MVC方法,看看拉斯穆斯例如: http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html

如果你的使用情况将会变得越来越复杂,看看如何Zend公司(http://framework.zend.com/manual/en/zend.controller.html)或Symfony的(https://github.com/symfony / symfony中/树/主/ src目录/ Symfony的/分量/路由)做自己的东西。



Answer 4:

选择任何流行的MVC,看看他们是如何实现它的引擎盖下。 此外,spl_autoload_register和命名空间是你的朋友。



文章来源: how to build a good router for php mvc