2010-11-29 2 views
6

фон

У меня есть Apache/2.2.15 (Win32) с PHP/5.3.2 настройки, обработки аутентификации.Невозможно получить переменные окружения Apache в PHP

<Directory /usr/www/myhost/private> 
    # core authentication and mod_auth_basic configuration 
    # for mod_authn_dbd 
    AuthType Basic 
    AuthName "My Server" 
    AuthBasicProvider dbd 

    # core authorization configuration 
    Require valid-user 

    # mod_authn_dbd SQL query to authenticate a user 
    AuthDBDUserPWQuery "SELECT Password,UserName,Realm,Access FROM authn WHERE user = %s" 
</Directory> 

Аутентификация работает нормально! Нет проблем.

Но в отношении к documentation, любое дополнительное поле вернулся из AuthDBDUserPWQuery будет введен в AUTHENTICATION_fieldname переменной в окружающей среде.

С phpinfo(), я могу видеть эти переменные с правильными значениями в «Apache Environment».

AUTHENTICATE_USERNAME
AUTHENTICATE_REALM
AUTHENTICATE_ACCESS

Проблема

Я не могу получать эти переменные окружения из моего PHP.

1 <?php 
2 $Access = apache_getenv('AUTHENTICATE_ACCESS',true); 
3 var_dump($Access); 
4 ?> 

Линия 3 печатает bool (false), указывающую, что переменная не найдена!
Однако, если я перехожу на другую переменную среды Apache, такую ​​как «HTTP_HOST», она работает.
.. и да, я пробовал getenv() тоже, такой же результат.

Существует также примечание, что сервер Apache должен быть скомпилирован с APR 1.3.0 для работы. Я использовал сборку Apache MSI с httpd.apache.org и, похоже, скомпилирован с APR выше версии 2. Поскольку я вижу их с phpinfo(), они должны быть доступны из PHP.

+2

* \ [♦ примечание: см. [История изменений] (http://stackoverflow.com/posts/4308886/revisions) для контекста этого комментария.] * Обычно мы не плачем о чьем-то английском (ваш довольно хорошо), и если форматирование вашего кода сосало, кто-то, вероятно, отредактировал бы его, чтобы он был хорошо читаемым. Кроме того, SO - это не то место, где людям говорят google/rtfm - googling/rtfming - это то, что могут ответить люди, так как они получат + rep для него, сообщая, что вы это сделаете, скорее всего, приведет к -rep. : p – ThiefMaster

+0

У меня нет ответов на ваш вопрос, но +1 за лучший структурированный вопрос, который я когда-либо видел. –

+0

Совершенно действительный вопрос, не нужно быть настолько защитным. :) Ответы RTFM обычно зарезервированы для многих, * много * худших (не) вопросов. – deceze

ответ

1

Я сделал работу вокруг,

Похоже, что это может быть PHP ошибка. Нашли некоторые связанные ошибки, о которых сообщалось для PHP 4, и, возможно, они еще не исправили их ...

Я сделал решение, которое мне действительно не нравится (потому что я обращаюсь к таблице пользовательских данных Apache), но кажется что у меня нет выбора.

//************************************************************* 
// If PHP failed to retrieve the AuthDBDUserPWQuery fields. 
// Connect to Apache authentication databaseand create the 
// envirnment variables manually 
// 
if (empty($_ENV['AUTHENTICATE_ACCESS'])) { 
    $Apache = mysql_connect('MyServerIP','MyUserName','MyPassword',false,MYSQL_CLIENT_SSL|MYSQL_CLIENT_COMPRESS); 
    mysql_select_db('MyDatabase',$Apache); 
    $SQLSet = mysql_query("SELECT Realm, Access FROM authenticationtable WHERE UserName='".$_SERVER['PHP_AUTH_USER']."' AND Password='".$_SERVER['PHP_AUTH_PW']."'"); 
    $SQLRow = mysql_fetch_array($SQLSet); 
    $_ENV['AUTHENTICATE_REALM'] = $SQLRow['Realm']; 
    $_ENV['AUTHENTICATE_ACCESS']= $SQLRow['Access']; 
    mysql_close($Apache); 
} 

Если PHP не удалось обновить $ _ENV правильно, это будет получить вошедшего в систему пользователя из одной и той же базы данных и таблицы, которые Apache использует для аутентификации. Затем дополнительные поля будут записаны в глобальную переменную $ _ENV, чтобы ее можно было использовать, как предполагается. Позже, когда исправлена ​​ошибка, она автоматически будет использовать исходный $ _ENV.

Если кто-нибудь может принести некоторые актуальную информацию по этой теме, я был бы счастлив ...

+1

И как это может быть забито?!? Я нашел решение своего опроса и разместил его, чтобы другие могли его увидеть. Если вы собираетесь голосовать, пожалуйста, укажите, почему?!? –

3

Я использовал это правило mod_rewrite в файле .htaccess, чтобы сделать переменную среды заголовка HTTP-авторизации доступной в $_SERVER['HTTP_AUTHORIZATION']. Я уверен, что это может быть адаптировано для ваших целей. Не уверен, если это лучшее решение, но это решение:

RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last] 
+0

+1 для попытки: D Мне нужно было прочитать RewriteRule, чтобы понять, что вы предложили. Но я не думаю, что это сработает. Если я понимаю это право,% {HTTP: Авторизация} уже присутствует в вашем HTTP-заголовке, и вы только «копируете» информацию в среду Apache. В моем случае AuthDBDUserPWQuery создает переменные среды Apache для каждого дополнительного поля (после пароля) из инструкции SQL. Эти значения больше отсутствуют. Может ли это быть ошибкой в ​​PHP, которую можно получить только предопределенные переменные Apache? –

+0

@Max Хм, я вижу ... У меня нет ничего другого, к сожалению. – deceze

0

Существует ключ в ответ deceze в.Он извлекает данные из $ _SERVER вместо $ _ENV.

Я установка Apache Env Var с

SenEnv my_var "истинным" в главном httpd.conf и не мог видеть его в $ _ENV. Это было в $ _SERVER.

0

Недавно я написал библиотеку, чтобы получать значения из переменных среды и анализировать типы данных PHP. Эта библиотека может использоваться для синтаксического анализа переменных среды для типов данных PHP (например, для каста целых чисел, float, null, boolean), синтаксического анализа сложных структур данных, таких как строка JSON, и многое другое с вкладом commnunity.

Библиотека доступна здесь: https://github.com/jpcercal/environment

Настройка ваши переменные окружения с .htaccess на примере:

SetEnv YOUR_ENV_VARIABLE_NAME the-value-of-your-env-var 

И чтобы получить значения из переменной окружения (независимо от окружающей среды CLI, Apache, Nginx , Встроенный сервер PHP и т. Д.):

<?php 
// ... 
require "vendor/autoload.php"; 
// ... 
var_dump(Cekurte\Environment\Environment::get("YOUR_ENV_VARIABLE_NAME")); 

Наслаждайтесь этим.