views:

101

answers:

5

Hi,

I'm thinking about how to find from where any function was called. The problem is that I need to find where the PHP is calling mail() function. One way will be to use register_tick_function(), but I'll need to open each file and check what is on each line. The project is huge, it will take really long to parse each file in PHP. Any other way? Or option how to override the mail() function?

+3  A: 

You can inspect the stack trace with debug_backtrace(). This will contain information about the calling method/function among others. See the manual for examples.

To add behavior to an existing function, wrap the function into your own function or class and then call this instead of the native function.

To completely redefine a native function, you'd have to install runkit. Then you could do runkit_redefine_function() (or use APD as suggested elsewhere).

If you just want to know where in your project mail() was called, e.g. you do not need to evaluate this at runtime, use your IDE's search function. Eclipse, Zend Studio and Netbeans can do file searches, so it should be very easy to find the calls and also to replace them.

Gordon
+6  A: 

To override the built-in mail function, take a look at override_function which is part of the Advanced PHP Debugger PECL extension - then you can use debug_backtrace to find out the caller details...

//define code to override mail function (note I've used php5.3 nowdoc syntax to avoid 
//the need to escape the dollar symbols!!
$code=<<<'CODE'
    $trace=debug_backtrace();
    $caller=array_shift($trace);

    echo 'mail() called by '.$caller['function']
    if (isset($caller['class']))
        echo 'in '.$caller['class'];
CODE;

//install override
override_function('mail', '$to,$subject,$msg,$hdrs,$params', $code);
Paul Dixon
-1 for not solving the problem. mail() is a built in function, there's no way to add the code you provided to it.
Sparr
boo for implying that I had not read your "complete answer" before you made your edits. I'll take away the -1 for it being accurate now, but no +1 for misleading comments.
Sparr
+2  A: 

The brute force approach would be to do a global search and replace in your code, replacing "mail\s(" with "my_mail(", then define my_mail and put whatever logging functionality you want there.

Sparr
+1  A: 

Why don't you simply search the source for "mail("?

Sjoerd
my guess is that the source contains many calls to mail() that are capable of generating the mail that is being sent, and he wants to figure out which one is actually doing it.
Sparr
A: 

I take it you have access to the source code?

Why not just use an editor like jEdit, and find all occurences of mail(* in all open buffers?

Or do you really need to know the line numbers at runtime? I can't imagine that you actually do.

It seems we all posted a similar answer at the same time. Voted up on both counts.