CodeIgniter PHP Framework - необходимо получить строку запроса

Я создаю сайт электронной коммерции с использованием 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

Для обработки ответа мне нужно получить данные строки запроса.


Извините, я не объяснил проблему ясно. Я получаю сообщение об ошибке "Страница не найдена" при получении ответа от сайта оплаты после оплаты.

Я попытался включить с uri_protocol = 'PATH_INFO' а также enable_query_strings = 'TRUE' в config.php, При поиске в Google я обнаружил, что это не будет работать, если я использую htaccess rewrite.

Я уже пытался изменить записи конфигурации, но это не работает.

12 ответов

Вы можете получить это так:

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

Смотрите это для получения дополнительной информации.

Я использую CodeIgniter уже более года. По большей части мне это очень нравится (я участвую в форуме и использую его во всех случаях, когда могу), но Я НЕНАВИЖУ, НАСТОЯЩИМ в этом утверждении в руководстве:

Уничтожает глобальный массив GET. Поскольку CodeIgniter не использует строки GET, нет никаких причин, чтобы это разрешать.

Предположение, что вам никогда не понадобится GET в приложении CodeIgniter, является ложным! Уже через несколько дней мне пришлось иметь дело с пост-бэк-страницами из PayPal и ClickBank (я уверен, что есть еще миллион). Угадайте, что они используют GET!!!

Существуют способы остановить это GET-сжатие, но это вещи, которые могут испортить другие вещи. Чего вы не хотите слышать, так это того, что вам нужно перекодировать все ваши представления, потому что вы включили строки запросов, и теперь ваши ссылки не работают! Внимательно прочитайте руководство по этому варианту!

Тот, который мне нравится (но не работает, потому что установка REQUEST_URI в config.php сломал мой сайт) расширяет класс Input:

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

Но самый лучший способ - это проверить print_r($_SERVER) по URL, где вам нужны переменные GET. Посмотрите, какой параметр протокола URI показывает ваши переменные GET и используйте его.

В моем случае я вижу, что мне нужно в REQUEST_URI

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

Это помещает вашу строку запроса обратно в суперглобальный $_GET для этого экземпляра страницы (вам не нужно использовать $_GET, это может быть любая переменная.)

РЕДАКТИРОВАТЬ

После публикации я обнаружил, что при использовании REQUEST_URI вы потеряете свой первый ключ массива строки запроса, если не удалите все до?. Например, URL, такой как /controller/method? One=1&two=2, заполнит массив $_GET в этом примере массивом ('method? One'=>1,'two'=>2). Чтобы обойти это, я использовал следующий код:

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']);
   }
}

Если вы хотите не разбирается строка запроса:

$this->input->server('QUERY_STRING');
// 98% functional
parse_str($_SERVER['REQUEST_URI'], $_GET);

Фактически это лучший способ справиться с отсутствием поддержки строк запроса $_GET в CodeIgniter. Я сам придумал это самостоятельно, но вскоре понял, что Бреттикус сделал то же самое, что вам пришлось немного изменить способ обработки первой переменной:

// 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 ) 

Откройте файл application/config/config.php и установите следующие значения:

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

$config['enable_query_strings'] = TRUE; 

Теперь строки запроса должны работать нормально.

Если вы используете mod_rewrite для удаления файла index.php, вы можете использовать следующий код для получения переменных GET (через $this->input->get()). Предполагая конфигурацию по умолчанию, назовите файл MY_Input.php и поместите его в каталог application/library.

Использование: $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;
    }


}

Установите свой конфигурационный файл

$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
}

Спасибо всем другим постерам. Вот что поразило меня:

    $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]

Вот полный рабочий пример того, как разрешить строки запросов в 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);

Наслаждаться:-)

Вот как я это сделал недавно. Надеюсь, поможет

<?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&morestuff=y

Вы можете создать хук 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);
                }
            }
        }
    }
}

?>

Вы можете создать правило в своем.htaccess, чтобы предотвратить запуск MOD_REWRITE на этой конкретной странице. Это должно позволить вам использовать _GET.

Другие вопросы по тегам