Подтвердить что ты не робот

Как именно PHP создает суперглобальные $_POST, $_GET, $_COOKIE и $_REQUEST?

Прошу прощения за неправильное название вопроса, я попытаюсь выяснить, в чем проблема.

Я работаю с сервером Mongrel2, и я пишу обработчик PHP, который имеет доступ к необработанным данным HTTP-запроса. Поскольку у меня есть PHP за Mongrel2, автоматическое создание переменных $_POST, $_GET, $_COOKIE и $_REQUEST не производится.

Вопрос: есть ли способ, которым я могу отправить необработанный HTTP-запрос в PHP-функцию (или что-нибудь еще), которая будет создавать суперглобальные переменные, которые обычно доступны при использовании Apache + PHP?

Примечание. Я могу разобрать HTTP-запрос вручную и самостоятельно создать эти переменные, но мне не удалось найти документацию о том, как именно PHP выполняет этот анализ HTTP и импортирует его в суперглобалы. Если возможно, я хотел бы автоматизировать этот процесс суперглобального создания без необходимости самостоятельно анализировать HTTP-запросы.

Спасибо за любой вклад.

4b9b3361

Ответ 1

Создание этих переменных обрабатывается глубоко внутри кишки PHP, в main/php_variables.c, в php_auto_globals_create_get() и подобных функциях. Из PHP 5.4.3:

static zend_bool php_auto_globals_create_get(const char *name, uint name_len TSRMLS_DC)
{
        zval *vars;

        if (PG(variables_order) && (strchr(PG(variables_order),'G') || strchr(PG(variables_order),'g'))) {
                sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC);
                vars = PG(http_globals)[TRACK_VARS_GET];
        } else {
                ALLOC_ZVAL(vars);
                array_init(vars);
                INIT_PZVAL(vars);
                if (PG(http_globals)[TRACK_VARS_GET]) {
                        zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]);
                }
                PG(http_globals)[TRACK_VARS_GET] = vars;
        }

        zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
        Z_ADDREF_P(vars);

        return 0; /* don't rearm */
}

Это приводит к вызову непосредственно в SAPI (например, модуль Apache/CGI/FastCGI/что угодно) для извлечения переменных. Я не думаю, что вы можете изменить способ, которым это работает, если вы находитесь в странной среде, где переменные GET/POST/etc не там, где PHP ожидает их.

Ответ 2

Я пытаюсь внести свой вклад в этот вопрос со знанием, которое я знаю.

Отправка HTTP-запроса с такими заголовками может дублировать переменную POST

POST /somepage.php HTTP/1.1
Host: www.domain.com
User-Agent: Mozilla/12.0
Content-Length: 31
Content-Type: application/x-www-form-urlencoded

parameter=value&testcode=value1

Также вы можете проверить HttpRequest libray PHP. [Начать здесь]. Для данных POST вы можете переопределить предыдущий контент POST с помощью HttpRequest::setPostFields() и установить для него свои собственные данные.

HttpRequest::setPostFields(array(
    "parameter" => "value"
));

Ответ 3

Найдено на php.net, возможно, это будет полезно:

$_POST = array();
$str = 'first=value&arr[]=foo+bar&arr[]=baz';
parse_str(html_entity_decode($str), $_POST);
print_r($_POST);

Array
(
    [first] => value
    [arr] => Array
        (
            [0] => foo bar
            [1] => baz
        )

)

Примечание:

Параметр magic_quotes_gpc влияет на выход этой функции, так как parse_str() использует тот же механизм, что использует PHP для заполнения переменных $_GET, $_POST и т.д.

http://php.net/manual/en/function.parse-str.php

Ответ 4

$_ POST, $_GET, $_COOKIE и $_REQUEST доступны в PHP каждый раз, также если php был запущен в командной строке. Эти массивы доступны для записи, вы можете добавить значения в массив $_POST и получить их в любом другом месте.

Этот код полностью корректен и работоспособен, если вы запускаете его с консоли:

<?php

$_POST['test'] = '1';
echo "\$_POST in global scope:\n";
var_dump($_POST);

function p() {
     echo "\$_POST in function scope:\n";

     var_dump($_POST);

     echo "Others super-global array in function scope:\n";
     var_dump($_REQUEST);
     var_dump($_COOKIE);

}

p();

Результат:

$_POST in global scope:
array(1) {
  'test' =>
  string(1) "1"
}
$_POST in function scope:
array(1) {
  'test' =>
  string(1) "1"
}
Others super-global array in function scope:
array(0) {
}
array(0) {
}

Изменить

Кроме того, вы можете создать класс и сохранить данные из HttpRequest в статическом поле. В этом случае вы можете использовать его с любого из них.