Php 将url字符串(路径和参数)解析为数组
只是在这里写一个小函数,需要一些优化帮助 所有请求都重定向到索引页 我有一个将url解析为数组的函数 url的类型描述为:Php 将url字符串(路径和参数)解析为数组,php,optimization,Php,Optimization,只是在这里写一个小函数,需要一些优化帮助 所有请求都重定向到索引页 我有一个将url解析为数组的函数 url的类型描述为: http://localhost/{user}/{page}/?sub_page={sub_page}&action={action} 例如: http://localhost/admin/stock/?sub_page=products&action=add 请求uri时,域被排除,因此my函数接受如下字符串: /admin/stock/?sub_pa
http://localhost/{user}/{page}/?sub_page={sub_page}&action={action}
例如:
http://localhost/admin/stock/?sub_page=products&action=add
请求uri时,域被排除,因此my函数接受如下字符串:
/admin/stock/?sub_page=products&action=add
我的功能如下,警告这是非常程序化的
对于那些不屑于阅读和理解的人,我在底部添加了一个解释;)
基本上有一个主if语句,一个路径是如果没有定义查询字符串(没有“?”),另一个路径是如果“?”确实存在
我只是想让这个功能更好
值得让它成为一门课吗
本质上,我需要一个函数,它将/{user}/{page}/?sub_page={sub_page}&action={action}
作为参数并返回
array(
"user" => {user},
"page" => {page},
"sub_page" => {sub_page},
"action" => {action}
)
干杯,Alex一些建议可以让这个功能更好 首先,使用而不是分解来分隔主机名、路径和查询字符串 第二,在决定是否有查询字符串之前,先编写解析路径的代码,因为您可以任意解析路径 第三,不要使用
foreach
循环来复制参数,而是像这样使用:
// put $return_uri_array last so $parameter_array can't override values
$return_uri_array = array_merge($parameter_array, $return_uri_array);
这是否应该是一个类取决于您的编程风格。一般来说,我总是使用类,因为在单元测试中模拟类更容易
最简洁的方法是这样一个正则表达式(没有完全测试,只是为了说明原理)
if(preg_匹配(')!http://localhost/(?P\w+(:/(?P\w+)/(?:\?子页面=(?P\w+)&操作=(?P\w+)!',$uri,$matches)){
返回$matches;
}
生成的数组也将具有匹配项的数字索引,但您可以忽略它们,或使用数组\u intersect\u keys
筛选所需的关键字。
\w+
模式匹配所有“word”字符,您可以将其替换为类似于[-a-zA-Z0-9\]
或类似的字符类
function uri_to_array($uri){
$result = array();
parse_str(substr($uri, strpos($uri, '?') + 1), $result);
list($result['user'], $result['page']) = explode('/', trim($uri, '/'));
return $result;
}
print_r(
uri_to_array('/admin/stock/?sub_page=products&action=add')
);
/*
Array
(
[sub_page] => products
[action] => add
[page] => stock
[user] => admin
)
*/
演示:如果您愿意
- 做得好
- 使用正则表达式
- 使用相同的方法解析所有URL:s(
不支持相对路径,下面称为parse_URL()
)only_path
$url = 'http://localhost/admin/stock/?sub_page=products&action=add';
preg_match ("!^((?P<scheme>[a-zA-Z][a-zA-Z\d+-.]*):)?(((//(((?P<credentials>([a-zA-Z\d\-._~\!$&'()*+,;=%]*)(:([a-zA-Z\d\-._~\!$&'()*+,;=:%]*))?)@)?(?P<host>([\w\d-.%]+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(\[([a-fA-F\d.:]+)\]))?(:(?P<port>\d*))?))(?<path>(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))|(?P<only_path>(/(([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))?)|([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*)))?(?P<query>\?([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*))?(?P<fragment>#([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*))?$!u", $url, $matches);
$parts = array_intersect_key ($matches, array ('scheme' => '', 'credentials' => '', 'host' => '', 'port' => '', 'path' => '', 'query' => '', 'fragment' => '', 'only_path' => '', ));
var_dump ($parts);
参考资料:
为了澄清,以下是用于制定正则表达式的相关文档:
- 或RFC3986 IPv4
- 或RFC2732 IPv6
看一下简化一些任务的方法。这看起来太复杂了。对于您想要的模式,一个简单的
preg\u match()
不是也有同样的作用吗?好吧,但是preg\u match不会返回关联数组??:你可以在结果中使用关联数组,如果你使用命名子模式谢谢,我现在就开始,发布我的结果。PCRE的东西太容易出错,并且是作为parse_url()的替代品出现的。parse_url()应该是起点。他问如何使他的函数“更好”。如果“更好”意味着代码更少,那么PCRE解决方案是最好的。如果“更好”意味着更少的代码加上对函数功能的清晰理解,那么正则表达式就不是最好的选择,我同意;-)
function uri_to_array($uri){
$result = array();
parse_str(substr($uri, strpos($uri, '?') + 1), $result);
list($result['user'], $result['page']) = explode('/', trim($uri, '/'));
return $result;
}
print_r(
uri_to_array('/admin/stock/?sub_page=products&action=add')
);
/*
Array
(
[sub_page] => products
[action] => add
[page] => stock
[user] => admin
)
*/
$url = 'http://localhost/admin/stock/?sub_page=products&action=add';
preg_match ("!^((?P<scheme>[a-zA-Z][a-zA-Z\d+-.]*):)?(((//(((?P<credentials>([a-zA-Z\d\-._~\!$&'()*+,;=%]*)(:([a-zA-Z\d\-._~\!$&'()*+,;=:%]*))?)@)?(?P<host>([\w\d-.%]+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(\[([a-fA-F\d.:]+)\]))?(:(?P<port>\d*))?))(?<path>(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))|(?P<only_path>(/(([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))?)|([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*)))?(?P<query>\?([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*))?(?P<fragment>#([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*))?$!u", $url, $matches);
$parts = array_intersect_key ($matches, array ('scheme' => '', 'credentials' => '', 'host' => '', 'port' => '', 'path' => '', 'query' => '', 'fragment' => '', 'only_path' => '', ));
var_dump ($parts);
// split the URL
preg_match ('!^((?P<scheme>[a-zA-Z][a-zA-Z\d+-.]*):)?(((//(((?P<credentials>([a-zA-Z\d\-._~\!$&'()*+,;=%]*)(:([a-zA-Z\d\-._~\!$&'()*+,;=:%]*))?)@)?(?P<host>([\w\d-.%]+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(\[([a-fA-F\d.:]+)\]))?(:(?P<port>\d*))?))(?<path>(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))|(?P<only_path>(/(([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*))?)|([a-zA-Z\d\-._~\!$&'()*+,;=:@%]+(/[a-zA-Z\d\-._~\!$&'()*+,;=:@%]*)*)))?(\?(?P<query>([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*)))?(#(?P<fragment>([a-zA-Z\d\-._~\!$&'()*+,;=:@%/?]*)))?$!u', $url, $matches);
$parts = array_intersect_key ($matches, array ('scheme' => '', 'credentials' => '', 'host' => '', 'port' => '', 'path' => '', 'query' => '', 'fragment' => '', 'only_path' => '', ));
// extract the user and page
preg_match ('!/*(?P<user>.*)/(?P<page>.*)/!u', $parts['path'], $matches);
$user_and_page = array_intersect_key ($matches, array ('user' => '', 'page' => '', ));
// the query string stuff
$query = array ();
parse_str ($parts['query'], $query);