Best way to access $_SERVER variables from c?

php.internals

Glenn Richmond

19 years ago
Hi All, I apologize if this is an extremely straight-forward question, but I'm trying to access the SERVER_NAME variable from PHP source (a tweak to protect against accessing disallowed directory paths in a shared environment without enabling safe mode). I've got the following code: if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name) != FAILURE) { // Got server name php_error_docref(NULL TSRMLS_CC, E_WARNING, "Base directory: %s, %s, %s", basedir, path, server_name); return 0; } else { // Unable to find server name php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find server_name hash."); return 0; } However, the value that is reported as SERVER_NAME appears to be giberish (the call succeeds, but the value doesn't make sense). I'm getting "lEÊ·èEÊ·EÊ·" for the value of the server name. Any idea what is going on here? I've also tried the get_env function without success, but I'm guessing this is only valid when running as a CGI script as opposed to mod_php5. Note that I'm just using the php_error_docref as debugging output at this point. Regards, Glenn.

Glenn Richmond

19 years ago
ok, worked it out - after a day and a half of trying to get it working, it hits me just after I post! Didn't realize the values were coming back as php hashes. For future newbie reference, here's the working code: zval **server_name = NULL; char* lookup_server_name; if (strcmp(basedir, "VIRTUAL_DOCUMENT_ROOT") == 0) { if (!PG(http_globals)[TRACK_VARS_SERVER] || zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name) == FAILURE) { // Unable to find server name php_error_docref(NULL TSRMLS_CC, E_WARNING, "SERVER_NAME variable is not set, cannot determine server name."); return 0; } else { // Convert the hash to a string convert_to_string_ex(server_name); // Convert the hash value to a char* for c processing lookup_server_name = estrndup(Z_STRVAL_PP(server_name), Z_STRLEN_PP(server_name)); // Non-zero result, error occured php_error_docref(NULL TSRMLS_CC, E_WARNING, "Base directory: %s, %s, %s", basedir, path, lookup_server_name); return 0; } } Glenn Richmond wrote:

Pierre Joye

19 years ago
Hi Glenn, On 11/21/06, Glenn Richmond <glenn.richmond@ilisys.com.au> wrote:
> ok, worked it out - after a day and a half of trying to get it working, > it hits me just after I post! Didn't realize the values were coming back > as php hashes. For future newbie reference, here's the working code: > > zval **server_name = NULL; > char* lookup_server_name; > > if (strcmp(basedir, "VIRTUAL_DOCUMENT_ROOT") == 0) { > if (!PG(http_globals)[TRACK_VARS_SERVER] || > zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, > "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name) == FAILURE)
You can use the HASH_OF macro, a bit cleaner : if (zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name) == SUCCESS) { ... } --Pierre