【问题标题】:Whats the best way to manage QUERY_STRING in php?在 php 中管理 QUERY_STRING 的最佳方法是什么?
【发布时间】:2010-10-11 04:46:54
【问题描述】:

我的一个网站有一些非常复杂的排序功能,除了分页,各种变量加起来就是一个非常复杂的 URL,管理起来非常麻烦。有没有办法有效地管理 QUERY_STRING?

我的意思是...如果 url 是 index.php?catid=3&sort=date&year=2009&page=2 并且我希望用户跳转到第 3 页,或者更改排序方法.....如何我是否会保留剩余的变量,而不使用 if/else 条件检查每个单独的变量,并将它们回显在链接到第 3 页或替代排序方法的链接中。

【问题讨论】:

    标签: php optimization query-string


    【解决方案1】:

    要处理实际查询字符串(字符串格式),您可以使用parse_str()。如果要构建查询字符串,请使用http_build_query()

    这些文档页面上有很多示例。

    如果由于某种原因您不能使用http_build_query,请查看我关于fastest way to implode an associative array 的问题。

    <?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
    

    【讨论】:

      【解决方案2】:

      PHP 为您提供了一个全局 $_GET ,它将您的查询字符串很好地解析为元素

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

      您可以取消设置不想传递的内容,然后通过以下方式移至新网址:

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

      【讨论】:

      • -1,内爆不会保留键,它只会将值连接在一起。
      • $_GET.slice() 应该做什么?这不是 PHP,因为 $_GET 是一个数组,因此没有可调用的方法。
      • 是的 / 脑子放屁 - 这些天我脑子里用的语言太多了
      【解决方案3】:

      如果您的意思是您希望第 3 页的链接仅是

      index.php?page=3
      

      或更改排序方法的链接将只是

      index.php?sort=date
      

      您必须将其他变量存储在 session variables(或 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>';
      ?>
      

      【讨论】:

        【解决方案4】:

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

        // 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() 上的文档(这是名称完全混乱的函数之一 - 没有人会期望该函数仅通过查看名称来完成它的工作)。

        【讨论】:

          【解决方案5】:

          我在一般的“为我构建一个可排序、可分页的表”类时遇到了完全相同的问题。这就是为什么有人在 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-vars 进行分页和排序(一个'东西)并且链接只改变那些(这是我现在主要做的)

          【讨论】:

            【解决方案6】:

            在查询字符串末尾添加变量名称和值(将页面更改为3):

            index.php?catid=3&sort=date&year=2009&page=2&x=page&y=3
            

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

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

            你可以在任何地方使用相同的链接,最后只需简单添加,并且编程量最少。

            【讨论】:

            • 有趣的解决方案,但它使事情变得过于复杂并导致生成重复页面,不利于 SEO。
            【解决方案7】:

            不要直接管理字符串,而是管理它的数组 (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;
            

            【讨论】:

            • 我知道有 $_GET 但这仅适用于当前请求。有时您需要解析任意数量的查询字符串。
            • 这正是 parse_str() 和 http_build_query() 本身所做的。
            猜你喜欢
            • 1970-01-01
            • 2010-09-18
            • 2010-09-30
            • 1970-01-01
            • 2021-08-31
            • 2012-04-08
            • 2010-09-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多