Если PHP работает в CGI-режиме

Прежде всего следует признать, что общего решения этой проблемы не существует. Более того, достоверно известно о существовании таких хостингов, где работа TAO.CMS/CMF на FastCGI вообще невозможна без специальных патчей. Именно поэтому в требованиях к хостингу четко сказано: CGI НЕЛЬЗЯ!

Однако, случаи-то разные бывают...

Краткий экскурс в теорию

Проблема PHP в CGI-режиме состоит в том, что в нем нет функции apache_request_headers, которая требуется для работы нашего фреймворка. Эту функцию, тем не менее, возможно сэмулировать, взяв данные из массива $_SERVER. Казалось бы, что проблема этим и решается. Но не тут-то было.

При обращении к закрытым разделам сайта (в частности, к админке) в возвращаемых данной функцией заголовках обязательно должен присутствовать заголовок Authorization, в котором содержится информация о логине и пароле пользователя при HTTP-Basic авторизации. Иначе не заработает админка. Вот в этом моменте и скрываются хтонические грабли. Логин и пароль в PHP передаются "как бог на душу положит". Иногда - вообще не передаются, и в этом случае "медицина бессильна". А вот если передаются, то чаще всего (но не всегда!) логин и пароль находятся в элементах массива $_SERVER - PHP_AUTH_USER и PHP_AUTH_PW.

Собственно эмуляция функции

Поместите эту функцию в тело файла index.php

function apache_request_headers()
{

	$names = array(
		'Host' => 'HTTP_HOST',
		'User-Agent' => 'HTTP_USER_AGENT',
		'Accept' => 'HTTP_ACCEPT',
		'Accept-Language' => 'HTTP_ACCEPT_LANGUAGE',
		'Accept-Encoding' => 'HTTP_ACCEPT_ENCODING',
		'Accept-Charset' => 'HTTP_ACCEPT_CHARSET',
		'Referer' => 'HTTP_REFERER',
		'Cookie' => 'HTTP_COOKIE',
		'Via' => 'HTTP_VIA',
		'X-Forwarded-For' => 'HTTP_X_FORWARDED_FOR',
		'Cache-Control' => 'HTTP_CACHE_CONTROL',
		'Connection' => 'HTTP_CONNECTION',
	);

	$headers = array();
	foreach($names as $h => $s) {
		if (isset($_SERVER[$s])) {
			$headers[$h] = $_SERVER[$s];
		}
	}

	$f_user = 'PHP_AUTH_USER';
	$f_pass = 'PHP_AUTH_PW';

	if (isset($_SERVER[$f_user])&&isset($_SERVER[$f_pass])) {
		$p = $_SERVER[$f_user].':'.$_SERVER[$f_pass];
		$headers['Authorization'] = 'Basic '.base64_encode($p);
	}

	return $headers;
}

Вполне возможно, что вам потребуется модификация этой функции для конкретного хостинга.

Метки: Хостинг
14.01.2014
Все статьи