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.