【问题标题】:CodeIgniter PHP Framework - Need to get query stringCodeIgniter PHP Framework - 需要获取查询字符串
【发布时间】:2011-01-11 09:17:31
【问题描述】:

我正在使用CodeIgniter 创建一个电子商务网站。

我应该如何获取查询字符串?

我正在使用Saferpay 支付网关。网关响应将是这样的:

http://www.test.com/registration/success/?DATA=<IDP+MSGTYPE%3D"PayConfirm"+KEYID%3D"1-0"+ID%3D"KI2WSWAn5UG3vAQv80AdAbpplvnb"+TOKEN%3D"(unused)"+VTVERIFY%3D"(obsolete)"+IP%3D" 123.25.37.43"+IPCOUNTRY%3D"IN"+AMOUNT%3D"832200"+CURRENCY%3D"CHF"+PROVIDERID%3D"90"+PROVIDERNAME%3D"Saferpay+Test+Card"+ACCOUNTID%3D"99867-94913159"+ECI%3D"2"+CCCOUNTRY%3D"XX"%2F>&SIGNATURE=bc8e253e2a8c9ee0271fc45daca05eecc43139be6e7d486f0d6f68a356865457a3afad86102a4d49cf2f6a33a8fc6513812e9bff23371432feace0580f55046c

为了处理响应,我需要获取查询字符串数据。


抱歉,我没有把问题解释清楚。付款后收到付款网站的响应时出现“找不到页面”错误。

我尝试在config.php 中启用uri_protocol = 'PATH_INFO'enable_query_strings = 'TRUE'。在谷歌搜索时,我发现如果我使用 htaccess rewrite 这将不起作用。

我已经尝试过更改配置条目,但它不起作用。

【问题讨论】:

    标签: php codeigniter frameworks


    【解决方案1】:

    你可以这样得到:

    $this->input->get('some_variable', TRUE);
    

    See this for more info.

    【讨论】:

      【解决方案2】:

      我已经使用 CodeIgniter 一年多了。在大多数情况下,我真的很喜欢它(我为论坛做出了贡献并在我可以使用的所有情况下使用它)但我讨厌手册中该声明的傲慢:

      销毁全局 GET 数组。自从 CodeIgniter 不使用 GET 字符串,没有理由允许 它。

      在 CodeIgniter 应用程序中永远不需要 GET 的假设是愚蠢的!在短短几天内,我就不得不处理来自 PayPal 和 ClickBank 的回发页面(我敢肯定还有一百万其他人。)猜猜看,他们使用 GET !!!

      有一些方法可以阻止这种 GET 挤压,但它们往往会搞砸其他事情。您不想听到的是您必须重新编码所有视图,因为您启用了查询字符串,现在您的链接已损坏!仔细阅读该选项的手册!

      我喜欢的一个(但没有工作,因为在 config.php 中设置 REQUEST_URI 破坏了我的网站)正在扩展 Input 类:

      class MY_Input extends CI_Input
      {
              function _sanitize_globals()
              {
                  $this->allow_get_array = TRUE;
                  parent::_sanitize_globals();
              }
      }
      

      但最好的严肃方法是在需要 GET 变量的 URL 处使用 print_r($_SERVER) 进行测试。查看哪个 URI 协议选项显示您的 GET 变量并使用它。

      就我而言,我可以看到我需要什么 REQUEST_URI

      // defeat stupid CI GET squashing!
      parse_str($_SERVER['REQUEST_URI'], $_GET);
      

      这会将您的查询字符串放回该页面实例的 $_GET 超级全局变量中(您不必使用 $_GET,它可以是任何变量。)

      编辑

      自从发布此内容后,我发现使用 REQUEST_URI 时,您将丢失第一个查询字符串数组键,除非您删除 ? 之前的所有内容。例如,像 /controller/method?one=1&two=2 这样的 URL 将使用 array('method?one'=>1,'two'=>2) 填充此示例中的 $_GET 数组。为了解决这个问题,我使用了以下代码:

      parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
      

      我想我应该提供一个例子,所以这里是:

      class Pgate extends Controller {
         function postback() {
            parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
            $receipt = $this->input->xss_clean($_GET['receipt']);
         }
      }
      

      【讨论】:

      • $_SERVER['REQUEST_URI'] 还是 $_SERVER['QUERY_STRING']?
      【解决方案3】:

      如果你想要未解析的查询字符串:

      $this->input->server('QUERY_STRING');
      

      【讨论】:

        【解决方案4】:
        // 98% functional
        parse_str($_SERVER['REQUEST_URI'], $_GET);
        

        这实际上是解决 CodeIgniter 中不支持 $_GET 查询字符串的最佳方式。实际上我自己想出了这个,但很快就意识到 Brettcus 所做的事情是你必须稍微修改处理第一个变量的方式:

        // 100% functional    
        parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
        

        我自己动手只是时间问题,但是使用这种方法是一种更好的单线解决方案,可以解决其他所有问题,包括修改现有的 URI 库,仅与控制器隔离在适用的情况下,无需对默认配置 (config.php) 进行任何更改

        $config['uri_protocol'] = "AUTO";
        $config['enable_query_strings'] = FALSE;
        

        有了这个,您现在可以使用以下内容:

        /controller/method?field=value
        /controller/method/?field=value
        

        验证结果:

        print_r($_GET); // Array ( [field] => value ) 
        

        【讨论】:

          【解决方案5】:

          打开 application/config/config.php 并设置以下值:

          $config['uri_protocol'] = "PATH_INFO";
          
          $config['enable_query_strings'] = TRUE; 
          

          现在查询字符串应该可以正常工作了。

          【讨论】:

            【解决方案6】:

            如果您使用 mod_rewrite 删除 index.php 文件,您可以使用以下代码获取 GET 变量(通过 $this->input->get())。假设默认配置,将文件命名为 MY_Input.php 并将其放在您的 application/libraries 目录中。

            用法:$this->input->get()

            class MY_Input extends CI_Input {
            
                function My_Input()
                {
                    parent::CI_Input();
            
                    // allow GET variables if using mod_rewrite to remove index.php
                    $CFG =& load_class('Config');
                    if ($CFG->item('index_page') === "" && $this->allow_get_array === FALSE)
                    {
                        $_GET = $this->_get_array();
                    }
            
                }
            
                /**
                 * Fetch an item from the GET array
                 * 
                 * @param string $index
                 * @param bool   $xss_clean
                 */
                function get($index = FALSE, $xss_clean = FALSE)
                {
                    // get value for supplied key
                    if ($index != FALSE)
                    {
                        if (array_key_exists(strval($index), $_GET))
                        {
                            // apply xss filtering to value
                            return ($xss_clean == TRUE) ? $this->xss_clean($_GET[$index]) : $_GET[$index];
                        }
                    }
                    return FALSE;
                }
            
                /**
                 * Helper function
                 * Returns GET array by parsing REQUEST_URI
                 * 
                 * @return array
                 */
                function _get_array()
                {           
                    // retrieve request uri
                    $request_uri = $this->server('REQUEST_URI');
            
                    // find query string separator (?)
                    $separator = strpos($request_uri, '?');
                    if ($separator === FALSE)
                    {
                        return FALSE;
                    }
            
                    // extract query string from request uri
                    $query_string = substr($request_uri, $separator + 1);
            
                    // parse query string and store variables in array
                    $get = array();
                    parse_str($query_string, $get);
            
                    // apply xss filtering according to config setting
                    if ($this->use_xss_clean === TRUE)
                    {
                        $get = $this->xss_clean($get);
                    }
            
                    // return GET array, FALSE if empty
                    return (!empty($get)) ? $get : FALSE;
                }
            
            
            }
            

            【讨论】:

            • 为什么还没有人将此标记为最佳答案?
            【解决方案7】:

            感谢所有其他海报。这对我来说很重要:

                $qs = $_SERVER['QUERY_STRING'];
                $ru = $_SERVER['REQUEST_URI'];
                $pp = substr($ru, strlen($qs)+1);
                parse_str($pp, $_GET);
            
                echo "<pre>";
                print_r($_GET);
                echo "</pre>";
            

            意思是,我现在可以做:

            $token = $_GET['token'];
            

            在 .htaccess 中我不得不改变:

            RewriteRule ^(.*)$ /index.php/$1 [L]
            

            到:

            RewriteRule ^(.*)$ /index.php?/$1 [L]
            

            【讨论】:

              【解决方案8】:

              这是一个完整的工作示例,说明如何在 Codeignitor 中允许查询字符串,例如在 JROX 平台上。只需将其添加到位于以下位置的 config.php 文件中:

              /system/application/config/config.php 
              

              然后你可以像平常一样使用 $_GET 或下面的类来获取查询字符串

              $yo = $this->input->get('some_querystring', TRUE);
              $yo = $_GET['some_querystring'];
              

              下面是代码:

              /*
              |--------------------------------------------------------------------------
              | Enable Full Query Strings (allow querstrings) USE ALL CODES BELOW
              |--------------------------------------------------------------------------*/
              
              /*
              |----------------------------------------------------------------------
              | URI PROTOCOL
              |----------------------------------------------------------------------
              |
              | This item determines which server global should 
              | be used to retrieve the URI string.  The default 
              | setting of 'AUTO' works for most servers.
              | If your links do not seem to work, try one of 
              | the other delicious flavors:
              |
              | 'AUTO'              Default - auto detects
              | 'PATH_INFO'         Uses the PATH_INFO
              | 'QUERY_STRING'      Uses the QUERY_STRING
              | 'REQUEST_URI'   Uses the REQUEST_URI
              | 'ORIG_PATH_INFO'    Uses the ORIG_PATH_INFO
              |
              */
              if (empty($_SERVER['PATH_INFO'])) {
                  $pathInfo = $_SERVER['REQUEST_URI'];
                  $index = strpos($pathInfo, '?');
                  if ($index !== false) {
                      $pathInfo = substr($pathInfo, 0, $index);
                  }
                  $_SERVER['PATH_INFO'] = $pathInfo;
              }
              
              $config['uri_protocol'] = 'PATH_INFO'; // allow all characters 
              
              $config['permitted_uri_chars'] = ''; // allow all characters 
              
              $config['enable_query_strings'] = TRUE; // allow all characters 
              
              parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
              

              享受:-)

              【讨论】:

                【解决方案9】:

                设置你的配置文件

                $config['index_page'] = '';
                $config['uri_protocol'] = 'AUTO';
                $config['allow_get_array']      = TRUE;
                $config['enable_query_strings'] = FALSE;
                

                和 .htaccess 文件(根文件夹)

                <IfModule mod_rewrite.c>
                    Options +FollowSymLinks
                    Options -Indexes
                    RewriteEngine On
                    RewriteBase /
                
                    RewriteCond %{REQUEST_FILENAME} !-f
                    RewriteCond %{REQUEST_FILENAME} !-d
                
                    RewriteCond $1 !^(index\.php)
                    RewriteRule ^(.*)$ index.php [L]
                
                
                </IfModule>
                

                现在你可以使用了

                http://example.com/controller/method/param1/param2/?par1=1&par2=2&par3=x
                http://example.com/controller/test/hi/demo/?par1=1&par2=2&par3=X
                

                服务器端:

                public function test($param1,$param2)
                {
                    var_dump($param1); // hi
                    var_dump($param2); // demo
                    var_dump($this->input->get('par1')); // 1
                    var_dump($this->input->get('par2')); // 2
                    var_dump($this->input->get('par3')); // X
                }
                

                【讨论】:

                  【解决方案10】:

                  您可以在 .htaccess 中制定规则,以防止您的 MOD_REWRITE 在该特定页面上触发。这应该允许您使用 _GET。

                  【讨论】:

                  • 如果他这样做了,那么 URL 需要将 index.php 放回其中。
                  【解决方案11】:

                  这是我最近的做法。希望对你有帮助

                  <?php 
                  //adapt this code for your own use
                                  //added example.com to satisfy parse_url
                          $url="http://www.example.com".$_SERVER["REQUEST_URI"];
                          $url=parse_url($url);
                                  //I'm expecting variables so if they aren't there send them to the homepage
                          if (!array_key_exists('query',$url))
                          {
                               redirect('/'); exit;
                          }
                          $query=$url['query'];
                  
                          parse_str($query,$_GET); //add to $_GET global array
                  
                          var_dump($_GET);
                  ?>
                  

                  致电:http://www.mydomain.com/mycontroller/myfunction/?somestuff=x&amp;morestuff=y

                  【讨论】:

                    【解决方案12】:

                    您可以创建一个 pre_system 挂钩。在您创建的钩子类中,您可以获取所需的查询参数并将它们添加到 $_POST 以进行正常的 CI 处理。我为 jQuery Ajax 助手做了这个。

                    例如:

                    (将此文件命名为 autocomplete.php 或您在挂钩中放置的任何文件名)

                    <?php
                    
                    /*
                    By Brodie Hodges, Oct. 22, 2009.
                    */
                    
                    if (!defined('BASEPATH')) exit('No direct script access allowed');
                    /**
                    *   Make sure this file is placed in your application/hooks/ folder.
                    *
                    *   jQuery autocomplete plugin uses query string.  Autocomplete class slightly modified from excellent blog post here:
                    *   http://czetsuya-tech.blogspot.com/2009/08/allowing-url-query-string-in.html 
                    *   Ajax autocomplete requires a pre_system hook to function correctly.  Add to your 
                    *   application/config/hooks.php if not already there:
                    
                        $hook['pre_system'][] = array(
                            'class'    => 'Autocomplete',
                                    'function' => 'override_get',
                                                    'filename' => 'autocomplete.php',
                                                    'filepath' => 'hooks',
                                                    'params'   => array()
                                                    );
                    
                    *                               
                    * 
                    */
                    
                    class Autocomplete {
                        function override_get() {
                            if (strlen($_SERVER['QUERY_STRING']) > 0) {
                                $temp = @array();
                                parse_str($_SERVER['QUERY_STRING'], $temp);
                                if (array_key_exists('q', $temp) && array_key_exists('limit', $temp) && array_key_exists('timestamp', $temp)) {
                                    $_POST['q'] = $temp['q'];
                                    $_POST['limit'] = $temp['limit'];
                                    $_POST['timestamp'] = $temp['timestamp'];
                                    $_SERVER['QUERY_STRING'] = "";
                                    $_SERVER['REDIRECT_QUERY_STRING'] = "";
                                    $_GET = @array();
                                    $url = strpos($_SERVER['REQUEST_URI'], '?');
                                    if ($url > -1) {
                                        $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 0, $url);
                                    }
                                }
                            }
                        }
                    }
                    
                    ?>
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2018-08-03
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-03-25
                      • 2017-05-07
                      • 1970-01-01
                      • 2016-01-18
                      相关资源
                      最近更新 更多