I've been digging a little deeper and have figured out that I probably could
retrieve what I want (realpath of first executed file) from included_files
hash (first entry, obviously). Unfortunately, doing it like this (sampled
from get_included_files() implementation):

    char *hentry;
    zend_hash_internal_pointer_reset(&EG(included_files));
    zend_hash_get_current_key(&EG(included_files), &hentry, NULL, 1);
    printf("%s", hentry);

only results in segfaults (in the very first zend_hash_... call). Am I using
wrong macros or something like that? I've checked the PHP sources (and
manually compiled function call trace) to make myself sure that
included_files hash gets destroyed AFTER the macro RSHUTDOWN functions are
called, so this should not be an issue.

Another hint, if I may ask for it? :)

Thanks,
b.


2010/8/9 Bostjan Skufca <bost...@a2o.si>

> I don't think I made myself exactly clear.
>
> There are 2 use cases I would like to consider:
> 1. CLI: by using "php /full/path/to/script.php" or "cd /full/path/to && php
> script.php"
> 2. Apache DSO: going to http://www.domain.com/script.php which in turn
> 'executes' script "/full/path/to/script.php"
>
> In both cases, in RINIT I would like to get full path (real path, if
> possible) of this /full/path/to/script.php. Is this possible or is your way
> the only viable solution (with performance penalty etc)?
>
> (The $_SERVER['SCRIPT_FILENAME'] was just a method to explain what I would
> like to have, albeit obviously a poor one:)
>
> Thanks again,
> b.
>
>
> 2010/8/9 Johannes Schlüter <johan...@php.net>
>
> On Mon, 2010-08-09 at 13:32 +0200, Bostjan Skufca wrote:
>> > Hi all!
>> >
>> > I am developing a small PHP extension and I ATM can't figure out how to
>> get
>> > to $_SERVER['SCRIPT_FILENAME'] content while in PHP_RINIT or
>> PHP_RSHUTDOWN
>> > function. Can someone please hint me with this one?
>>
>> The simple answer is: You can't. The closest you can get is a char *
>> SG(request_data).request_uri
>>
>> The more complex answer is: It is only stored for being used in
>> $_SERVER. So you can read it from there. The engine has a "just in time"
>> mode to avoid creating _SERVER when not needed, we need it so we first
>> have to trigger the creation of that variable, then one can search
>> through the global symbol table and then search in there:
>>
>>
>> zval **server, **tmp;
>> zend_auto_global_disable_jit("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
>> if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"),
>>  (void**)&server) == FAILURE || Z_TYPE_PP(server) != IS_ARRAY) {
>>    /* error handling */
>>    return;
>> }
>> if (zend_hash_find(Z_ARRVAL_PP(server), "SCRIPT_FILENAME",
>> sizeof("SCRIPT_FILENAME"), (void**)&tmp) == FAILURE || Z_TYPE_PP(tmp) !=
>> IS_STRING) {
>>    /* error handling */
>>    return;
>> }
>> /* work with tmp */
>>
>> As this accesses the userspace $_SERVER you should do this during RINIT,
>> else the value might be wrong. While this adds some cost to every
>> request (populating $_SERVER plus two hash lookups), it can be optimized
>> a tiny bit by precalculating the hash and using zend_hash_quick_find().
>>
>> The code above is untested.
>>
>> johannes
>>
>>
>>
>

Reply via email to