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

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

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

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

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

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

Создание этих переменных обрабатывается глубоко внутри кишки 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 ожидает их.

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

Отправка 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" )); 

Найденный на 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

$ _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 в статическом поле. В этом случае вы можете использовать его с любого из них.