urlencode 问题
Issue with urlencode
我在过滤系统中对 & 符号进行编码时遇到问题。
例如,如果第一个过滤器用于品牌且品牌名称为 'Head & Shoulders',则 url 应类似于 website/category/brand-head+%26+shoulders,但过滤器仅在 url是website/category/brand-head-%252526+肩膀。
如果选择了另一个过滤器,例如身高,如果 url 是 website/category/brand-head-%25252526+shoulders 等品牌过滤器有效,我必须在百分号前添加另一个 25。
这是品牌过滤器代码
if($brand == false){
$data['brands'] = array();
$brands = $attributes->getBrands($av_list, $_GET['c']);
$brandTotalCnt = 0;
if(!empty($brands)){
foreach ($brands as &$brand) {
if($av_list){
$cur_av_list = $av_list . $brand['brand'];
$cur_av_uri = $_GET['av'] . $brand['brand'];
} else {
$cur_av_list = $brand['brand'];
$cur_av_uri = $brand['brand'];
}
$tmp_uri = explode('/', $ln_uri);
$tmp_uri_array = $attributes->remove_items_by_value($tmp_uri, 'brand');
$new_uri = implode('/', $tmp_uri_array);
$brandTotalCnt += $brand['num'];
$data['brands'][] = array(
'brand' => ucwords(strtolower($brand['brand'])),
'num' => $brand['num'],
'href' => $url->link('/c/'.$_GET['c'], '/brand-'. urlencode(strtolower($brand['brand'].'1')). $new_uri)
);
}
}
$data['brandTotalCnt'] = $brandTotalCnt;
}
每个过滤器的网址解码
if(isset($brand)){
$sql .= " AND brand = '".urldecode($brand)."'";
}
if(isset($gramaj)){
$height= $_GET['height'];
$sql .= " AND height= '".urldecode($height)."'";
}
这是来自我的 htaccess
# rewrite /category/brand-mybrand/country-mycountry/offer-yes/new-yes
# to /index.php/brand-mybrand/country-mycountry/offer-yes/new-yes?c=category
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^c/([^/]+)/([^-]+.+)/?$ /index.php/?c= [L,QSA]
# rewrite /index.php/brand-mybrand/country-mycountry/offer-yes/new-yes?c=category
# converts any /name-val/ to query parameter name=val in every rewrite
# stopping when there is no part left after /index.php
RewriteRule ^(index\.php)/([^-]+)-([^/]+)(/.*)?$ /?= [L,QSA]
PHP 自动解析查询字符串并 URL 在启动期间对值进行解码,当它填充 $_GET[]
时。
当您生成 URL 时 urlencode()
值是正确的,但您不能 urldecode()
从 $_GET[]
.
中选择的值
更新:
正如 Apache documentation 中所解释的:
mod_rewrite
has to unescape URLs before mapping them, so backreferences are unescaped at the time they are applied
如果您的重写规则采用部分路径并将其放入查询字符串中,标志 [B]
(转义反向引用)指示引擎使用未转义的 URL 来匹配规则.
您的问题有两种解决方案:
- (简单解决方案):生成 URL 到 不 包含非字母数字字符;仅使用字母、数字和破折号 (
-
),您就安全了;
(高级解决方案):将 [B]
标志添加到受影响的重写规则中:
RewriteRule ^c/([^/]+)/([^-]+.+)/?$ /index.php/?c= [L,QSA,B]
我在过滤系统中对 & 符号进行编码时遇到问题。
例如,如果第一个过滤器用于品牌且品牌名称为 'Head & Shoulders',则 url 应类似于 website/category/brand-head+%26+shoulders,但过滤器仅在 url是website/category/brand-head-%252526+肩膀。
如果选择了另一个过滤器,例如身高,如果 url 是 website/category/brand-head-%25252526+shoulders 等品牌过滤器有效,我必须在百分号前添加另一个 25。
这是品牌过滤器代码
if($brand == false){
$data['brands'] = array();
$brands = $attributes->getBrands($av_list, $_GET['c']);
$brandTotalCnt = 0;
if(!empty($brands)){
foreach ($brands as &$brand) {
if($av_list){
$cur_av_list = $av_list . $brand['brand'];
$cur_av_uri = $_GET['av'] . $brand['brand'];
} else {
$cur_av_list = $brand['brand'];
$cur_av_uri = $brand['brand'];
}
$tmp_uri = explode('/', $ln_uri);
$tmp_uri_array = $attributes->remove_items_by_value($tmp_uri, 'brand');
$new_uri = implode('/', $tmp_uri_array);
$brandTotalCnt += $brand['num'];
$data['brands'][] = array(
'brand' => ucwords(strtolower($brand['brand'])),
'num' => $brand['num'],
'href' => $url->link('/c/'.$_GET['c'], '/brand-'. urlencode(strtolower($brand['brand'].'1')). $new_uri)
);
}
}
$data['brandTotalCnt'] = $brandTotalCnt;
}
每个过滤器的网址解码
if(isset($brand)){
$sql .= " AND brand = '".urldecode($brand)."'";
}
if(isset($gramaj)){
$height= $_GET['height'];
$sql .= " AND height= '".urldecode($height)."'";
}
这是来自我的 htaccess
# rewrite /category/brand-mybrand/country-mycountry/offer-yes/new-yes
# to /index.php/brand-mybrand/country-mycountry/offer-yes/new-yes?c=category
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^c/([^/]+)/([^-]+.+)/?$ /index.php/?c= [L,QSA]
# rewrite /index.php/brand-mybrand/country-mycountry/offer-yes/new-yes?c=category
# converts any /name-val/ to query parameter name=val in every rewrite
# stopping when there is no part left after /index.php
RewriteRule ^(index\.php)/([^-]+)-([^/]+)(/.*)?$ /?= [L,QSA]
PHP 自动解析查询字符串并 URL 在启动期间对值进行解码,当它填充 $_GET[]
时。
当您生成 URL 时 urlencode()
值是正确的,但您不能 urldecode()
从 $_GET[]
.
更新:
正如 Apache documentation 中所解释的:
mod_rewrite
has to unescape URLs before mapping them, so backreferences are unescaped at the time they are applied
如果您的重写规则采用部分路径并将其放入查询字符串中,标志 [B]
(转义反向引用)指示引擎使用未转义的 URL 来匹配规则.
您的问题有两种解决方案:
- (简单解决方案):生成 URL 到 不 包含非字母数字字符;仅使用字母、数字和破折号 (
-
),您就安全了; (高级解决方案):将
[B]
标志添加到受影响的重写规则中:RewriteRule ^c/([^/]+)/([^-]+.+)/?$ /index.php/?c= [L,QSA,B]