Is there a way to trace all calls to a certain function?
The purpose is to plug-in a debug function when "listening" to a function call.
For example, I will say "listen to all calls to mysqli_query()", so I can send the function name (and perhaps the arguments) to a debug/log function.
There is no built-in way to intercept calls to arbitrary functions for logging.
However, the xdebug debugging suite may be able to help you with its execution trace functionality. You'll be able to log both function calls and the arguments involved.
Related
I started to use CakePHP (1.2) a few months ago to add small features to the company's application and I'm not too familiar with it.
We test locally then on a development server before merging to a production server.
I want a controller action to be called every hour with what I assumed to be the best way to do this through my researches, a cron job.
Attempt 1
After reading these,
http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-actions-from-cron-and-the-command-line
http://book.cakephp.org/1.2/en/view/110/Creating-Shells-Tasks
I could implement something without errors, but the action is not executed.
Based on these examples, I added a file named cron_dispatcher.php in my app directory (not app/webroot) and then did this command from the app dir
php cron_dispatcher.php /controller/action/param
Still nothing happened but it works perfect when I call it through the url.
Attempt 2
I tried creating a shell (email.php) that would call the action in /app/vendors/shells/.
<?php
class EmailShell extends Shell {
public function main() {
$this->out('Test');
}
}
?>
This successfully outputs Test in the console using
cake email main
but then I cannot find how to call the controller's action. I have tried
$this->requestAction('/controller/action');
I have also tried to make the call from a different function than the main in the shell.
I have tried to include the controller in the $uses variable as I would with a model but that didn't work (and it doesn't make sense I think)
I don't think creating a task is the solution either as I don't want to duplicate the sendEmails function hence why I'm looking for a way to just call the controller's action from a shell or whatever!
There is probably some theory I'm missing, thanks
Solution
I moved some methods from the controller to a model and I was able to call them from a shell.
App::import('Component', 'Email');
class SendMemosShell extends Shell {
var $uses = array(
'Memo',
);
public function main() {
}
public function sendEmails () {
$this->Email =& new EmailComponent(null);
$memoList = $this->Memo->getMemos();
//...
}
}
This link helped
http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html
edit : clarified some of the information and added the solution
It is a quite common issue actually, ran into it also.
A controller is deciding how to handle a request and starting that task. In this case there is no need for a controller since you have a shell task, the task is already clear.
Knowing that, it does not make sense to call a controller method.
So rethink your options, and yes this is a quite difficult one. For example you might decide that sending the e-mail is a business logic step so it should be in the model. Another option is to separate it totally (that's what we like most).
In that case you will have to create a queue where you put in all e-mails to send. That is a good design since you then know the amount of logic in the controller goes down and it is separated. That way you get an e-mail service.
For example you could ask the service to send a "new user" mail. Then you add the User object to it and it should handle itself. That way you can even scale since your service could be for example outsourced, you could expand multiple servers on the service etc.
Edit:
Good questions.
Steps to take:
Centralize the "sending e-mail" process first. So choose one location where to put it. The you can decide: Add to send e-mail to a queue or call the service directly. For example you could add shell task for sending the e-mails.
Call the shell: Now you have the problem to call the shell. In general you don't want to. Why not? Because a shell (a task) could run for a long time. So that's why we use queues in between. So you can ask the queue or let the queue message you that something is done. For example think about a mail server which is down. You have to retry etc. That should not be in a web request because the user is waiting for response.
Third step is to call the shell from your cron, now that's easy since you are already on the command line so you could use standard calls.
Anyhow, there are options to do a direct call from a controller but you should not. This post gives some very interesting insights:
CakePHP: Run shell job from controller
Edit 31/08/'13: See the events system of CakePHP also for some examples: http://book.cakephp.org/2.0/en/core-libraries/events.html
Depending on what needs to be done, I often keep these methods in my controller actions. At the top of the action I check $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'] to ensure only the website can call the action. Then in cron I would curl or wget this address.
It has its benefits - easier to run locally during development (just enter the url in your browser), plus there are some differences between running cli version of php and apache version, as well as the request variables (eg. cake can't get the website domain/address through cli like you can running as apache module, so absolute links to the website using html helper don't work).
I'm using wordpress. I want to view like a backtrace for all the function that wordpress calls. Is this possible with php only or if not, where can i insert debug_backtrace() to view all the function call??
debug_backtrace() (when dumped) will show you the function calls and includes leading to the function within which you call the trace. You can't ask it to do a stack for the whole application (unless the whole application is just one long series of function calls and includes, and in that case you'd still have to find the last step and put the trace call in there).
So for Wordpress, if you're trying to get a feel for the application by trial-and-error, you could try adding the trace in places where you think it is likely.
I was wondering, can you make a function or something, that looks for other function calls across the site? I think, that if there is a master page, you could include it at the very top and it should work sitewise.
But I have no idea how to do this.
Kind of like debug_backtrace();, but global. In other words, a function that does something with a function that has been called after this function.
Well, I see that you could do this with a specific call_user_func();, therefore track everything what's going on, but.. any dynamic way?
Thanks in advance!
Goal
The goal of this is to dynamically keep chain of called functions. So at some moment, for example, I require a value back from 3rd function in chain, so I can simply retrieve it with something like $calls[2]; // the stored returned value or an array containing info about function + returned value.
And it adds function data to chain on each call, where 1st call's $key = 0. So for debugging purposes, when my function fails which is x function in a row, I'd love to know information about previously called functions, maybe one has returned wrong value, resulting in error at some part later on.
It looks like you are looking for some AOP technique. You could write the weaved code to return immediately if some (global) flag (show trace) is not set, otherwise print the backtrace.
PHP doesn't support AOP directly but you can either patch the PHP core or use tools to create (transform the) code based on the AOP weavings. I haven't used it for PHP yet, so you have to google.
I don't believe there is, and I doubt if it would work and would be useful. Functions in turn call other functions, even the internal ones. Even the logging functions are functions themselves, so you end up with an enormous amount of information with which you can do virtually nothing relevant. If such a solution exists (it may), it won't be developed in PHP itself, but be a module that is loaded by or compiled in PHP.
If you want to log method calls to class instances, you could make some hook. You can make a class that implements __call. Then, for an instance you want to log, assign that instance to an instance of your log class, and assign that log class instance to the variable in which the original class was stored.
Then, each method call is directed to your class and you can log each call before you call the original method.
Give a try to diyism_trace.php:
http://code.google.com/p/diyism-trace/
I have Zend AMF working great in my application, but I'm trying to figure out how to call multiple asynchronous functions with a single connection. For example, let's say I have a service called "MyService" and two functions called "init" and "getData". Can I create a connection, call "MyService.init" THEN "MyService.getData" within the same remote object? If so, how...if not, what is a better solution?
Of course, in this scenario, I can just combine init and getData into one function...but, the problem in the actual scenario is that there are many more methods that will need to run after "init". Thanks!
I have an unanswered question that I asked here I believe for the same reason as yours. I would love to know how to call multiple methods or even better, classes over one connection.
Anyway, in your case where you are talking about methods, with no answer on how to call them from the flex side, I would either make a 3rd method that calls those two, or allow some kind of object or parameter passing for init and let init call getData.
Another thought - maybe you need to consider what is happening in init and whether you really need it or need to call it directly from the client - for example, in order to getData (or put or etc), you always have to have been initialized? So getData should probably check to see if it has been initialized and init if it has not.
I'm currently using register_shutdown_function() for multiple purposes. One use is for handling fatal errors, while the other is for logging resources used during execution like time, memoryusage etc.
Currently I register two different shutdown functions, but on one test only the first ran while the other seemed to fail. Now this could ofcourse be triggered by some error within the function itself so I have rewritten it, but is it possible an error was caused by using several register_shutdown_function calls? So what is considered best practice here, to registert two different functions or just make the call to one function that handles the different tasks?
Is it also safe (and possible) to make the function load a class for errorhandling if a fatal error occurs or should I keep the functionality within the function itself?
The final question I got is if there's a better way to handle fatal errors than using shutdown functions? I tried using set_error_handler, but it does not cover all errortypes so some errors will not trigger this.
Hope these questions are well formulated and clear. My goal is to keep the code as solid as possible and I could not find any decent answers to the questions I had.
*Edit: Found the answer to my first question, registering several functions should be no problem so the error had to be within the function itself. Leaving the question up to get answers to whether there's a better ways to handle fatal errors.
IIRC, if you have multiple shutdown functions registered, they will be executed in the order in which they were registered; and you should never have an exit statement in any, otherwise subsequent shutdown functions will not be run. That means you need to take great care if you have multiple functions rather than a single shutdown function.
However, if you're passing different arguments to the different functions, you should ensure that you have default values for them all in case the functions are called (perhaps triggered by an error) before all the appropriate variables are set.
Personally, I register multiple functions, for similar purposes to yourself; but I'm very careful about the logic within them, and the order of registration.
It's also not a good idea to use includes or similar in shutdown functions (especially where one is an exception handler), in case the include itself triggers an exception