我的一个网站在分页之上有一些非常复杂的排序功能,各种变量加起来就是一个非常复杂的 URL,管理起来非常麻烦。有没有办法有效地管理 QUERY_STRING?
我的意思是...如果网址是 index.php?catid=3&sort=date&year=2009&page=2 并且我希望用户跳转到第 3 页,或者更改排序方法.....我将如何保留剩余的 var 不使用 if/else 条件检查每个单独的 var,并在链接到第 3 页或替代排序方法的链接中回显它们。
我的一个网站在分页之上有一些非常复杂的排序功能,各种变量加起来就是一个非常复杂的 URL,管理起来非常麻烦。有没有办法有效地管理 QUERY_STRING?
我的意思是...如果网址是 index.php?catid=3&sort=date&year=2009&page=2 并且我希望用户跳转到第 3 页,或者更改排序方法.....我将如何保留剩余的 var 不使用 if/else 条件检查每个单独的 var,并在链接到第 3 页或替代排序方法的链接中回显它们。
PHP 为您提供了一个全局 $_GET ,它将您的查询字符串很好地解析为元素
$_GET['catid'] will be '3'
$_GET['sort'] will be 'date'
$_GET['year'] will be '2009'
ETC
您可以取消设置您不想传递的内容,然后通过以下方式移至新网址:
$get = array_intersect_key($_GET, array_keys($_GET));
unset($get['sort']);
$url = 'target.php?' . http_build_query($get);
要处理实际的查询字符串(字符串格式),您可以使用parse_str()
. 当您要构建查询字符串时,请使用http_build_query()
.
这些文档页面上有很多示例。
如果由于某种原因您不能使用http_build_query
,请查看我关于内爆关联数组的最快方法的问题。
<?php
$QueryString = 'catid=3&sort=date&year=2009&page=2'; // sample querystring
parse_str($QueryString, $HttpQuery);
print_r($HttpQuery); // will be an associative array
$HttpQuery['page'] = 3; // change any values
$NewQueryString = http_build_query($HttpQuery); // rebuild the querystring
如果您的意思是您希望第 3 页的链接仅
index.php?page=3
或更改排序方法的链接将只是
index.php?sort=date
您必须将其他变量存储在会话变量(或 cookie,如果您希望它们持续更长时间)中。
像这样的东西:
<?php
session_start();
foreach($_GET as $var => $val) {
// filter any malicious stuff and invalid variables out of $var and $val here
// like
if (in_array($var, $array_of_valid_variable_names)) {
if ($var == 'page') $val = intval($val);
$_SESSION[$var] = $val;
}
}
// do stuff based on the values stored in $_SESSION
echo '<a href="index.php?page='.($_SESSION['page'] + 1).'">Next page</a>';
?>
尽管此处提供的大多数解决方案都可以使用,但我认为最简单的方法是
// parse query string into an array
$queryData = array();
parse_str($_SERVER['QUERY_STRING'], $queryData);
/*
* ... manipulate array $queryData
*/
// rebuild query string
$queryString = http_build_query($queryData, null, '&'); // or use & if you don't need XHTML compliance
就是这样。请参阅有关http_build_query()
and的文档parse_str()
(这是名称完全混乱的函数之一 - 没有人会期望该函数仅通过查看名称来完成它的工作)。
对于一般的“为我构建一个可排序的、可分页的表”类,我遇到了完全相同的问题。这就是为什么有人在 php.ini 中发明了称为“函数”的子过程。
您必须创建一个函数来准确处理链接构建过程。像这样:
/**
* $set: associative array of changing vars
* $unset : normal array of vars to delete
**/
function get_link($set,$unset=array())
{
$set+=$_GET;
if ($unset && is_array($unset))
foreach($unset as $idx)
unset($set[$idx]);
if ($set)
foreach($set as $name=>$value)
$pairs[]=$name.'='.urlencode($value);
return $_SERVER['SCRIPT_NAME']."?".join('&',$pairs);
}
未经测试的代码!动动脑筋
或者你可以使用 $_SESSION-vars 进行分页和排序(一个'东西)并且链接只改变那些(这是我现在主要做的)
在查询字符串的末尾添加变量名称和值(将页面更改为 3):
index.php?catid=3&sort=date&year=2009&page=2&x=page&y=3
然后,在提取 $_GET 之后,使用一个简单的函数来检查是否设置了 x 和 y。
如果是,则将名称包含在 x 中的变量设置为值 y。
您可以在任何地方使用相同的链接,最后只需简单添加,并且编程量最少。
不要直接管理字符串,而是管理它的数组( key => value )表示,并仅在需要时将其转换回字符串。
一种可能的方法:
function explodeQueryString( $queryString )
{
$parts = array();
if ( strlen( $queryString ) > 1 && substr( $queryString, 0, 1 ) == '?' )
{
$q = explode( '&', substr( $queryString, 1 ) );
foreach( $q as $part )
{
list( $key, $value ) = explode( '=', $part );
$parts[ urldecode( $key ) ] = urldecode( $value );
}
}
return $parts;
}
function implodeQueryString( array $arguments )
{
$parts = array();
foreach( $arguments as $key => $value )
{
$parts[ ] = sprintf( '%s=%s', urlencode( $key ), urlencode( $value ) );
}
return sprintf( '?%s', implode( '&', $parts ) );
}
// $query = $_GET;
$query = '?something=1&somethingelse=2&page=1&yetsomethingelse=3';
$q = explodeQueryString( $query );
print_r( $q );
$q[ 'page' ] += 1;
$query = implodeQueryString( $q );
echo $query;