Link to home
Start Free TrialLog in
Avatar of elepil
elepil

asked on

PHP: Basic question about __FILE__

Let's say I have a function called outputFile($source, $outputFileName, $message), and that it lives in a file called utils.php.

When I invoke this function, I always pass __FILE__ for the first parameter (i.e., $source). Let's say I'm calling that function while in index.php. So when I call the function like this: outputFile(__FILE__, "someFileName", "Hello World"), it would output to my log file something like this:

[Source=index.jsp]Hello World!

Open in new window


I'm kind of getting tired of having to type __FILE__ all the time when I call my outputFile function. Is there a way for my function to internally pick up which file it is being invoked from? In other words, if I were in index.php, is there a way my outputFile() function can know it was invoked from index.php and use that as the $source? I know if I hardcoded __FILE__ in outputFile(), it's going to output "utils.php" (where it lives) rather than where it was invoked.

Thanks.
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

If you're getting tired of typing anything, you're in the wrong profession.  Programmers are actually secretary / typists with additional skills as programmers.

As for your function to 'know' where it's being invoked from?  I've never heard of such a thing.  But then I never use '__FILE__' anyway.  After looking it up, I see why.  On shared hosting where most of my customers are, an absolute path is useless because shared hosting frequently blocks access thru an absolute path.  All you can use is paths relative to your web root.

http://php.net/manual/en/language.constants.predefined.php
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of elepil
elepil

ASKER

The day I cease getting tired of repetition is the day I stop making function libraries to make my life and future projects easier. Programming is one of the few professions where laziness is a virtue. All I'm trying to do here is streamline tasks, trying to do things in less steps than more. If I can create a function with two arguments than three, I'd choose that.

With PHP being so rich and numerous in functions, I was hoping people more knowledgeable in PHP than I might know of a function that allows an invoked function to somehow detect where it was invoked from. If that sounds like a bizarre expectation, remember the magic functions of PHP that allow one to create classes with no getters or setters and somehow end up populated in full.

I don't need an absolute path, just some indication where the function was invoked that I could output to my log file, just so I'd know which file the function was invoked from.
Avatar of elepil

ASKER

JulianH, now that's what I'm talking about!

Since debug_backtrace() returns an array, I think I might be able to programmatically construct a "bread crumb" and output it into my log file; this way, I can do away with __FILE__ altogether. Thanks, JulianH!
You are welcome
Avatar of elepil

ASKER

By the way. Dave, regarding what you said:

Programmers are actually secretary / typists with additional skills as programmers.

If all you do are forms and database calls, then you'd be a glorified secretary with great copy/paste skills, and you probably wouldn't deserve good pay.

I have yet to find a programmer job like that though. In all the work I've done, there always some challenge. Just in the application I'm currently working on, I had to make a series of JavaScript constructor functions that act as self-contained components (e.g. an elaborate highly-customizable tooltip, validator functions that work with my tooltip() function for highly flexible field validation, reusable constructor functions for slide shows, reusable functions for <div> overlays on any section of the page, etc.), things I don't think secretaries would even imagine doing. These are the stuff I've done since I started my transitioned to the PHP platform. Prior to that when I was doing java with Adobe Flex, I was making reusable custom components for clients, as well as dealing with Adobe Flex's tree and datagrid components while employing drag and drop. If you can find a secretary who can do all that at a near-secretary's pay scale, please send him/her my way, I will hire the individual.
Avatar of elepil

ASKER

Good riddance to __FILE__. fo() will always tell you what file and line number it's in. Anywhere in your application, no matter which function level your program execution is in, you can output any string to an output file for debugging.

/**
 * 'fo' stands for file output. Writes specified text output to a specified filename, providing a top to
 * bottom execution stacktrace path.
 * @param String $output    The text content to be outputted to the file.
 * @param String $filename  The output filename. Defaults to '/_foLog' if not
 *                          provided.
 * 
 * Example: fo("Hello World"); // outputs "Hello World" to "/_foLog"
 *          fo("Boo", "/myFile"); // outputs "Boo" to "/myFile"
 */
function fo($output, $filename='/_foLog') {
    $desc = "";
    $arr = debug_backtrace();

    $desc .= "PROGRAM EXECUTION ORDER:\n";
    for ($i=count($arr)-1; $i>=0; $i--) {
        /* If 'file' is undefined, an error is output to php_error_log. 
         * Assigning a value of '<unknown>' to prevent the error. */
        if (!isset($arr[$i]['file'])) {
            $arr[$i]['file'] = '<unknown>';
        }
        /* If 'line' is undefined, it will bomb out. Assigning '0' to prevent 
         * an error */
        if (!isset($arr[$i]['line'])) {
            $arr[$i]['line'] = '0';
        }
        if ($i == count($arr)-1) {
            $desc .= count($arr)-$i . ':' . $arr[$i]['file'] . ' at line ' . $arr[$i]['line'] . "\n";
        } else {
            $desc .= count($arr)-$i . ':' . $arr[$i]['file'] . ' at line ' . $arr[$i]['line'] . 
                 ' inside ' . $arr[$i+1]['function'] . "()\n"; 
        }
    }

    $time = strftime("%Y-%m-%d %H:%M:%S", time());
    $handle = fopen($_SERVER["DOCUMENT_ROOT"] . "/" . $filename, "a");
    fwrite($handle, '[' . $time . ']' . "\n");
    fwrite($handle, $desc);
    fwrite($handle, 'OUTPUT: ' . "\n");
    fwrite($handle, $output . "\n\n");
    fclose($handle);
}

Open in new window