在自己的PHP框架中管理URL路由 [英] Manage URL routes in own php framework

查看:101
本文介绍了在自己的PHP框架中管理URL路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个PHP框架,我对此有些疑问...



该框架采用以下方式获取网址:
http:/web.com/site/index



需要第一个参数加载控制器( site ),然后加载特定操作(索引)。



如果在基本URL中安装框架可以正常工作,但是如果将框架安装在这样的子文件夹中:
http://web.com/mysubfolder/controller/action



我的脚本将其解析为controller = mysubfolder 和action = controller



如果子文件夹更多,结果将更糟。



这是我的路线代码:

  Class Route 
{
private $ _htaccess = TRUE;
private $ _suffix = .jsp;

公共功能params()
{
$ url =’’;

//实际的del Directorio实际的del脚本ejecutandose。
// basename(dirname($ _ SERVER [’SCRIPT_FILENAME']));;

if($ this-> _htaccess!== FALSE):
//没有子目录的网络,通过stynat.dyndns.org/subdir/
// muestra el subdir como引物参数
$ url = $ _SERVER ['REQUEST_URI'];
if(isset($ set($ _ SERVER ['QUERY_STRING'])&&!empty($ _ SERVER ['QUERY_STRING']))):
$ url = str_replace(?。$ _SERVER [' QUERY_STRING'],'',$ url);
endif;
else:
if(isset($ _ SERVER ['PATH_INFO'])):
$ url = $ _SERVER ['PATH_INFO'];
endif;
endif;

$ url = explode(’/’,preg_replace(’/ ^(\ /)/’,’,$ url));
var_dump($ url);

var_dump($ _ GET);

}
}

感谢您的帮助。

解决方案

是的,我想我知道如何解决这个问题。



(免责声明:我知道您知道其中的大部分内容,但是我将为可能不了解某些陷阱的其他人解释所有内容)



使用PATH_INFO和。 htaccess



在php中有一个窍门,如果您转到以下路径:



http://web.com/mysubfolder/index.php/controller/action



您将在 $ _ SERVER ['PATH_INFO'] 变量

$ b $中获得 / controller / action b

现在您需要做的是获取一个.htaccess文件(或等效文件),并告诉您的php脚本当前文件夹的深度。



为此,请将.htaccess文件放入 mysubfolder中。

  mysubfolder 
.htaccess
索引hp

.htaccess应该包含:

  

#上的RewriteEngine#如果存在目录或文件,则直接使用它
RewriteCond%{REQUEST_FILENAME}!-f
RewriteCond%{ REQUEST_FILENAME}!-d

#否则将其转发到index.php
RewriteRule(。*)index.php / $ 1

(我使用了 yii框架手册作为参考,我还建议使用 html5样板



基本上,您已将其设置为将所有内容重定向到URL中特定位置的index.php。



现在,如果您访问:< a href = http://web.com/mysubfolder/index.php/controller/action rel = nofollow> http://web.com/mysubfolder/index.php/controller/action



现在您可以从 $ _ SERVER ['PATH_INFO'] 获得正确的路径 / controller / action / p>

除非您访问 http:/,否则不会有任何价值/web.com/mysubfolder/ 因为.htaccess文件将忽略重写,因为 http:// web。 com / mysubfolder / 路径请求实际存在的mysubfolder / index.php并被拒绝,谢谢您 RewriteCond%{REQUEST_FILENAME}!-f



ifsetor 函数



为此,您可以使用名为 ifsetor 的超级方便功能(我不记得我从哪里得到的)

 函数ifsetor(& $ variable,$ default = null){
return isset($ variable)? $ variable:$ default;
}

它的作用是引用可能存在或不存在的变量并提供默认值(如果它不存在而不会引发任何通知或错误)



现在,您可以使用它来像这样安全地获取PATH_INFO变量



在您的index.php中

 函数ifsetor(& $ variable,$ default = null) {
return isset($ variable)? $ variable:$ default;
}
$ path = ifsetor($ _ SERVER ['PATH_INFO'],'/’);
var_dump($ path);

php 5.4还具有这种新的较短的三元格式,如果您不关心通知,就可以使用(我愿意)

  $ path = $ _SERVER ['PATH_INFO']?:'/'; 



处理QUERY_STRING



现在从技术上讲,您没有获得URL,它只是其路径部分,并且将不包含query_string,例如访问



http: //web.com/mysubfolder/index.php/test?param=val



您只会在$ path变量中获得 / test,要获取查询字符串,请使用 $ _ SERVER ['QUERY_STRING'] 变量



index.php

 函数ifsetor(& $ variable,$ default = null){
return isset($ variable)? $ variable:$ default;
}
$ path = ifsetor($ _ SERVER ['PATH_INFO'],'/’);
$ fullpath =($ _SERVER ['QUERY_STRING'])? $ path。’?’。$ _ SERVER ['QUERY_STRING']:$ path;
var_dump($ fullpath);

但这可能取决于您的需求



$ _ SERVER ['QUERY_STRING']与$ _GET



还要记住, $ _ SERVER ['QUERY_STRING'] 变量与 $ _ GET $ _ REQUEST 变量不同,因为它保留了查询字符串中的重复参数,例如例如:



访问此页面



http://web.com/mysubfolder/controller/action?foo=1&foo=2&foo=3



如果要给您一个类似于

$的 $ _ SERVER ['QUERY_STRING'] b
$ b

 ?foo = 1& foo = 2& foo = 3 

$ _ GET 变量将是这样的数组:

  array(
'foo'=>'3'
);



如果您没有.htaccess



您可以尝试利用SCRIPT_NAME来发挥自己的优势

  list($ url)= explode('?',$ _ SERVER [ 'REQUEST_URI']); 
list($ basepath)=爆炸('index.php',$ _ SERVER ['SCRIPT_NAME']);
$ url = substr($ url,strlen($ basepath));

如果您想炸毁像我这样的东西:)



您的案例



  Class Route 
{
private $ _htaccess = TRUE;
private $ _suffix = .jsp;

公共功能params()
{
$ url =’’;

//实际的del Directorio实际的del脚本ejecutandose。
// basename(dirname($ _ SERVER [’SCRIPT_FILENAME']));;

if($ this-> _htaccess!== FALSE):
//没有子目录的网络,通过stynat.dyndns.org/subdir/
// muestra el subdir como引物参数
list($ url)= explode('?',$ _ SERVER ['REQUEST_URI']);
$ basepath = dirname($ _ SERVER [’SCRIPT_NAME’]);
$ basepath =($ basepath ===’//)? $ basepath:$ basepath。’/’;
$ url = substr($ url,strlen($ basepath));
else:
if(isset($ _ SERVER ['PATH_INFO'])):
$ url = $ _SERVER ['PATH_INFO'];
$ url = preg_replace(’| ^ / |’,’,$ url);
endif;
endif;

$ url = explode(’/’,$ url);
var_dump($ url);

var_dump($ _ GET);


}
}

我希望这样帮助



PS抱歉,回复晚了:(


I'm creating a PHP Framework and I have some doubts...

The framework takes the url in this way: http:/web.com/site/index

It takes the first parameter to load controller (site) and then loads the specific action (index).

If you've installed the framework in a base URL works ok, but if you install it in a subfolder like this: http://web.com/mysubfolder/controller/action

My script parses it as controller = mysubfolder and action = controller.

If you have more subfolders the results will be worst.

This is my Route code:

Class Route
{
    private $_htaccess = TRUE;
    private $_suffix = ".jsp";

    public function params()
    {
        $url='';

        //nombre del directorio actual del script ejecutandose.
        //basename(dirname($_SERVER['SCRIPT_FILENAME']));

        if($this->_htaccess !== FALSE):
            //no está funcionando bien si está en un subdirectorio web, por ej stynat.dyndns.org/subdir/
            // muestra el "subdir" como primer parámetro
            $url = $_SERVER['REQUEST_URI'];
            if(isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])):
                $url = str_replace("?" . $_SERVER['QUERY_STRING'], '',$url);
            endif;
        else:
            if(isset($_SERVER['PATH_INFO'])):
                $url = $_SERVER['PATH_INFO'];
            endif;
        endif;

        $url = explode('/',preg_replace('/^(\/)/','',$url));
        var_dump($url);

        var_dump($_GET);

    }
}

Thanks for any help you can give.

解决方案

Yes, I think I know how to fix that.

(Disclaimer: I know that you know most of this but I am going to explain everything for others who may not know some of the gotchas)

Using PATH_INFO and .htaccess

There is a trick in php where if you go to a path like:

http://web.com/mysubfolder/index.php/controller/action

you will get "/controller/action" in the $_SERVER['PATH_INFO'] variable

Now what you need to do is take a .htaccess file (or equivalent) and make it tell your php script the current folder depth.

To do this, put the .htaccess file into the "mysubfolder"

mysubfolder
    .htaccess
    index.php

.htaccess should contain:

RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule (.*) index.php/$1

(I used the yii framework manual as reference, I also recommend using the html5 boilerplate)

Basically you set it up to redirect everything to index.php at a specific point in the url.

Now if you visit: http://web.com/mysubfolder/index.php/controller/action

Now you can get the right path "/controller/action" from $_SERVER['PATH_INFO']

Except it's not going to have any value if you visit http://web.com/mysubfolder/ because the .htaccess file will ignore the rewrite because the http://web.com/mysubfolder/ path requests the mysubfolder/index.php which actually exists and gets denied thank yo RewriteCond %{REQUEST_FILENAME} !-f.

ifsetor function

For this you can use this super handy function called ifsetor (I don't remember where I got it)

function ifsetor(&$variable, $default = null) {
    return isset($variable)? $variable: $default;
}

What it does is take a reference to a variable that might or might not exist and provide a default if it does not exist without throwing any notices or errors

Now you can use it to take the PATH_INFO variable safely like so

In your index.php

function ifsetor(&$variable, $default = null) {
    return isset($variable)? $variable: $default;
}
$path = ifsetor($_SERVER['PATH_INFO'],'/');
var_dump($path);

php 5.4 also has this new shorter ternary format which you can use if you don't care about notices (I do)

$path = $_SERVER['PATH_INFO']?:'/';

Handling the QUERY_STRING

Now tecnically you are not getting a URL, it is merely its path part and will not contain the query_string, for example when visiting

http://web.com/mysubfolder/index.php/test?param=val

you will only get '/test' in the $path variable, to get the query string use the $_SERVER['QUERY_STRING'] variable

index.php

function ifsetor(&$variable, $default = null) {
    return isset($variable)? $variable: $default;
}
$path = ifsetor($_SERVER['PATH_INFO'],'/');
$fullpath = ($_SERVER['QUERY_STRING'])? $path.'?'.$_SERVER['QUERY_STRING']:$path;
var_dump($fullpath);

But that might depend on your needs

$_SERVER['QUERY_STRING'] vs $_GET

Also keep in mind that the $_SERVER['QUERY_STRING'] variable is different from the $_GET and $_REQUEST variables because it keeps duplicate parameters from the query string, for example:

Visiting this page

http://web.com/mysubfolder/controller/action?foo=1&foo=2&foo=3

if going to give you a $_SERVER['QUERY_STRING'] that looks like

?foo=1&foo=2&foo=3

While the $_GET variable is going to be an array like this:

array(
    'foo'=>'3'
);

If you don't have .htaccess

You can try using the SCRIPT_NAME to your advantage

list($url) = explode('?',$_SERVER['REQUEST_URI']);
list($basepath) = explode('index.php',$_SERVER['SCRIPT_NAME']);
$url = substr($url,strlen($basepath));

If you like to blow up stuff like me :)

Your case

Class Route
{
private $_htaccess = TRUE;
private $_suffix = ".jsp";

public function params()
{
    $url='';

    //nombre del directorio actual del script ejecutandose.
    //basename(dirname($_SERVER['SCRIPT_FILENAME']));

    if($this->_htaccess !== FALSE):
        //no está funcionando bien si está en un subdirectorio web, por ej stynat.dyndns.org/subdir/
        // muestra el "subdir" como primer parámetro
        list($url) = explode('?',$_SERVER['REQUEST_URI']);
        $basepath = dirname($_SERVER['SCRIPT_NAME']);
        $basepath = ($basepath==='/')? $basepath: $basepath.'/';
        $url = substr($url,strlen($basepath));
    else:
        if(isset($_SERVER['PATH_INFO'])):
            $url = $_SERVER['PATH_INFO'];
            $url = preg_replace('|^/|','',$url);
        endif;
    endif;

    $url = explode('/',$url);
    var_dump($url);

    var_dump($_GET);


}
}

I hope this helps

P.S. Sorry for the late reply :(

这篇关于在自己的PHP框架中管理URL路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆