什么是在php中管理QUERY_STRING的最佳方法?

5
我的一个网站有一些非常复杂的排序功能,加上分页和各种变量,导致URL非常复杂,这是一个巨大的痛点。有没有办法有效地管理QUERY_STRING?
我的意思是...如果URL是index.php?catid=3&sort=date&year=2009&page=2,并且我希望用户跳转到第3页或更改排序方法.....如何保留其余变量而不检查每个单独的变量并使用if/else条件将它们输出到链接中,以链接到第3页或备选排序方法。
7个回答

4
为了处理实际的查询字符串(字符串格式),您可以使用 parse_str()。当您想要构建查询字符串时,请使用 http_build_query()。这些文档页面上有很多例子。
如果由于某种原因您无法使用 http_build_query,请查看我的问题,了解关于将关联数组implode为字符串的最快方法
<?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

PHP提供了一个全局变量$ _GET,其中包含您的查询字符串,所有精美解析成元素

$_GET['catid'] will be '3'
$_GET['sort'] will be 'date'
$_GET['year'] will be '2009'

你可以取消你不想传递的内容,然后通过类似以下方式移动到新的网址:
```php header('Location: new_url.php?' . http_build_query($_GET)); ```

等等

$get = array_intersect_key($_GET, array_keys($_GET));
unset($get['sort']);
$url = 'target.php?' . http_build_query($get);

-1,implode不会保留键,它只会将值连接在一起。 - matpie
$_GET.slice()应该做什么?这不是PHP,因为$_GET是一个数组,因此没有可调用的方法。 - Stefan Gehrig
是的 / 大脑短路 - 最近我的脑海里使用了太多种编程语言。 - Scott Evernden

1
如果您的意思是希望链接仅指向第三页,那么可以这样做。
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>';
?>

1

虽然这里提供的大多数解决方案都可以工作,但我认为最简单的方法是

// 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, '&amp;'); // or use & if you don't need XHTML compliance

就是这样。请参阅http_build_query()parse_str()的文档(这是其中一个函数的名称完全混乱 - 没有人会仅凭名称来预期函数执行其所做的操作)。


0

我曾经遇到过一个通用的“构建可排序、可分页表格”的类的完全相同的问题。这就是为什么有人在php中发明了称为“函数”的子过程。

您必须创建一个处理链接构建过程的函数,如下所示:

/**
* $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 变量进行分页和排序(等等),并且只更改链接中的这些变量(这是我现在主要做的事情)


0
将变量名和值添加到查询字符串的末尾(将页面更改为3):
index.php?catid=3&sort=date&year=2009&page=2&x=page&y=3

然后,在提取 $_GET 后,使用一个简单的函数来检查 x 和 y 是否已设置。

如果已设置,则将名称包含在 x 中的变量设置为值 y。

您可以在每个地方使用相同的链接,并在结尾处进行简单的添加,编程量很小。


有趣的解决方案,但它让事情变得太复杂,并导致生成重复的页面,对于SEO不利。 - matpie

-1
不要直接管理字符串,而是管理它的数组(键=>值)表示,并且只在需要时将其转换回字符串。
一种可能的方法是:
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;

我知道有 $_GET 但它仅适用于当前请求。有时您需要解析任意数量的查询字符串。 - Kris
这正是parse_str()和http_build_query()本地支持的功能。 - matpie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接