PHP Profiler - получение клиентского IP и URL из расширения PHP с использованием C ++ - PullRequest
0 голосов
/ 12 сентября 2018

Я создал расширение php на c ++, которое отслеживает граф вызовов для каждого запроса. А теперь я хочу получить данные об удаленном IP-адресе и URL-адресе для каждого запроса.При попытке в CentOS 7.5 и PHP 5.6.36 (Потокобезопасность отключена), когда пользователь отправляет каждый запрос (браузер), apache передаст управление модулю PHP при обработкев фазе ответа.PHP_RINIT_FUNCTION () вызывается для каждой транзакции из движка Zend.Я попытался получить имя сервера и удаленный адрес и их данные в функции PHP_RINIT_FUNCTION (apm) следующим образом:

zval *args;
char * name = "REMOTE_ADDR";
int len = sizeof("REMOTE_ADDR");
if ( (zend_hash_find(&EG(symbol_table), name,len, (void **) &args) != FAILURE) || PG(http_globals)[TRACK_VARS_SERVER] || zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, name,len, (void **) &args) != FAILURE)
 {
 // success
 //converts args(zval*) to string 
 }
else
{
    //failed
    //can't get REMOTE address
}

Является ли вышеуказанный подход правильным ??Если так, это становится неудачным для каждого запроса .. Где я неправ?Какова альтернатива, если таковые имеются?

1 Ответ

0 голосов
/ 13 сентября 2018

В прошлом я успешно выполнял чтение этих значений из переменной суперглобального массива $_SERVER.Чтобы использовать $_SERVER (особенно из контекста RINIT), вы должны убедиться, что его автоматический глобальный обратный вызов был вызван.PHP обычно вызывает это при первом доступе к пользовательскому пространству (другими словами, PHP лениво загружает суперглобальные переменные).

Чтобы сделать это, вы ищите значение zend_auto_global из хеш-таблицы auto_globals и вызываете auto globalПерезвоните.Вы должны всегда проверять, чтобы убедиться, что $_SERVER не загружен заранее;хотя в вашем случае вы вызываете его из RINIT, поэтому он не будет загружаться всегда.

После вызова автоматического глобального обратного вызова вы теперь можете обращаться к $_SERVER, как и к любой другой глобальной переменной вsymbol_table hashtable.

Вот пример из моего расширения под названием uniauth (полный текст на Github см. по этой ссылке ):

/* Make sure $_SERVER is auto loaded already. */
if (!zend_hash_exists(&EG(symbol_table),"_SERVER",8)) {
    if (zend_hash_find(CG(auto_globals),"_SERVER",8,(void**)&auto_global) != FAILURE) {
        auto_global->armed = auto_global->auto_global_callback(auto_global->name,
            auto_global->name_len TSRMLS_CC);
    }
    else {
        zend_throw_exception(NULL,"could not activate _SERVER",0 TSRMLS_CC);
        return 0;
    }
}

Inэта конкретная часть кодовой базы, расширение генерирует URI перенаправления, используя информацию в $_SERVER.Вот код, который показывает использование серверных переменных для генерации URI (см. эту ссылку для полного контекста на Github):

/* Get information about the protocol, host and port number from the _SERVER
 * superglobal. We use HTTPS, HTTP_HOST and SERVER_PORT keys to resolve the
 * scheme, host and port. I know of no better way to do this unfortunately
 * with the PHP/ZEND API. The sapi globals just don't have what I need.
 */
if (zend_hash_find(&EG(symbol_table),"_SERVER",8,(void**)&arr) == FAILURE) {
    zend_throw_exception(NULL,"no _SERVER superglobal",0 TSRMLS_CC);
    return 0;
}
server = Z_ARRVAL_PP(arr);
if (zend_hash_find(server,"HTTPS",6,(void**)&val) != FAILURE) {
    if (Z_TYPE_PP(val) != IS_STRING || strcmp(Z_STRVAL_PP(val),"off") != 0) {
        https = 1;
    }
}
if (zend_hash_find(server,"HTTP_HOST",10,(void**)&val) != FAILURE
    && Z_TYPE_PP(val) == IS_STRING)
{
    host = Z_STRVAL_PP(val);
}
else {
    zend_throw_exception(NULL,"no HTTP_HOST within _SERVER found",0 TSRMLS_CC);
}

В комментарии я оплакиваю фактчто нет способа сделать это без подражания тому, что вы делаете в коде пользовательского пространства.Вы можете получить доступ к глобальной структуре SAPI в расширении, но оно не обладает всей информацией, необходимой моему (и вашему) проекту.Подробнее см. соответствующие структуры в заголовках PHP.

...