Get a called functions list in PHP - php

In PHP, get_included_files() returns an array with the names of included files.
In a similar fashion, is there any way to get an array with the names of called functions with parameters?

In this way, Is any way to get an array with the names of called functions with parameters?
No.
What you can do is a debug_backtrace() which will show all the function calls (with parameters) that lead to the execution of the line you are doing the backtrace from (the "call stack"), but that's different from all functions that were ever called in the script.
What do you want to do? Maybe there's a different approach.

I was searching for something similar and found xdebug's tracing very useful.
Here's an example of how it could look like:
http://devzone.zend.com/1135/tracing-php-applications-with-xdebug/

I was trying to achieve what you want and finally came up with an reasonable solution.
Make a class named Debug and include that above every file you want to debug in. Build yourself a function that prints nicely the information stored in $calls.
class Debug {
private static $calls;
public static function log($message = null)
{
if(!is_array(self::$calls))
self::$calls = array();
$call = debug_backtrace(false);
$call = (isset($call[1]))?$call[1]:$call[0];
$call['message'] = $message;
array_push(self::$calls, $call);
}
}
Call this function everytime you declare a function first line in the functionbody: Debug::log($message(optional) )

Not that I'm aware.
You can however use debug_backtrace to get the currently active function/method hierarchy.

I don't think there's a way to do what you want. Sorry.
The closest I can get is the function_exists() function, which will tell you whether a specific function has been loaded.
What exactly do you want to achieve here? I can't see a use case (outside of a php_info() type screen) that would require a list of available functions.

You will have to install it as an extension, but a profiler like XHProf will give you a breakdown of which functions are called and how long they take, as well as a callgraph.

XHProf or Webgrind/KCachegrind will show you the functions called, but not their parameters.
You could also use get_defined_functions, which gives you a list of all functions defined. But it won't show you which functions have actually been called, and with what parameters.
If you really need to know the parameters, I don't know of any tools other than a custom logger like the one Henze provided in his answer.

Related

it is possible to extend a php function?

My question is if it's possible to extend a declared function.
I want to extend mysql_function to add mysql query that insert into a table some logs : 'query' - the parameter of mysql_query, date,page...etc
My question is if it's possible to extend a declared function.
No.
You can extend a class method and call parent::methodname() to run the previous code (which is almost what you ask for), but for normal functions, there is no way to do this.
There are some esoteric PHP extensions that allow overriding functions, but I assume that's not what you need and their use is rarely practical.
What you probably want to do is create a new function, and call the existing function in it.
No, you cannot do that. Either enable the MySql Query Logs or wrap the code doing the queries into a Logging Decorator or use an abstraction like Zend_Db that can take a Profiler or use a transparent logging plugin for mysqlnd
You need to write a function that will take your query, log the sql first, runs your query, then return the results.
E.G
<?php
function mysql_query_log($sql)
{
mysql_query('insert into .... values ...');
$r = mysql_query($sql);
$results;
//do the normal thing you do with mysql here
return $results;
}
This is not extending a function though, you can only extend a class
It's not possible.
You should have created your own API (or use an existing one) to access the DB so when you need logging you can simply enhance your own API function. It also comes very handy if you need some custom error handling function. Refactor the code.
Well.. PHP says this: http://php.net/manual/en/function.override-function.php
from http://php.net/manual/en/function.rename-function.php
bool rename_function ( string $original_name , string $new_name )
Renames a orig_name to new_name in the global function table. Useful
for temporarily overriding built-in functions.
I believe that if you rename the original to original_mysql_query, then add your replacement function which does your logging and then calls original_mysql_query etc, that you will achieve your goal, assuming that you have the way to inject the rename on every page that will call MySQL_query. Most large sites have common code that is included at the top of every page that could do that for you.
There is also a built in php function called override_function (mentioned by ChrisH). It is not fully documented in the php man page but the user comments below the doc give you the information that you need to use it if you prefer it to the rename_function function. There was a discussion about being limited to one override if you needed to call the original function from the replacement. Using the rename_function instead of the override function eliminates that potential restriction.

Hooking into function calls in php

A little background: At runtime I would like to be able to inspect the currently called functions javadoc-style documentation, to determine its formal (typed) declaration. This would allow runtime type checking (for simple and complex types) by means of reflection (at a cost) during debugging and testing, something that I would find immensely helpful.
So, in php I would like for a user defined function to get called whenever any other function is about to get called. That is, if a function foo() gets called, I would like to have my callHookHandler() function called immediately before.
One solution would be to implement __call() in all user defined classes, but that is both unwieldy and doesn't include support for functions defined outside classes, so I am looking for a better solution.
This sounds a bit of a fun one so I'm going to give answering it a try.
I hope this helps you. Let me know how it goes.
So, what you are asking can be done, and here's how:
For Functions:
Get all defined functions with $function = get_defined_functions().
Loop through the $functions['user'] key and inspect each one with the ReflectionFunction class. You'll need to get:
The comment using ->getDocComment()
The arguments using ->getParameters()
Do some magic (I'll let you figure out how to parse the comment using some regular extressions and match it up with the parameter list from the reflection. Don't forget optional parameters!)
Rename the function using runkit_function_rename
Generate code in a string that checks the parameters and calls the renamed function
Generate a parameter list as a string
Create a new function with runkit_function_add using the code you generated in step #5 and the parameter list from step #6.
For Classes:
Get a list of classes with $classes = get_declared_classes();
Loop through each one and inspect it with ReflectionObject and ->getMethods() to get the methods. Make sure that the class is not internal with ->isInternal() because we can't do anything about the internal classes.
In an inner loop... go through each method using the ReflectionMethod class. Get the arguments and PHPDoc/JavaDoc comments just like you did with normal functions.
Do the same thing you did with the functions only use runkit_method_add and runkit_method_rename instead.
Downsides:
You won't be able to do the checking on internal class methods and functions (which is fine because they won't have doc comments anyway).
This is a lot of work! I left a lot of parts up to your imagination to avoid this being the length of a short book.
Please send me this or open source it and let me know when you finish, I really want to use this myself. Contact info is on my website which is in my profile ;)
Alternatively:
You can use XDebug's function trace along with reflection then analyze the results after the fact so that you don't have to dynamically edit the code. If you want to write unit-test you could even automate it.
Hope type checking makes it into future versions of PHP and wait: https://wiki.php.net/rfc/typechecking
Notes:
This class reference has a potentially useful example of parsing docComments in the comments section of the page:
http://us.php.net/manual/en/class.reflectionmethod.php
References
get_defined_functions
get_declared_classes
ReflectionFunction
ReflectionObject
ReflectionMethod
runkit
Alternative way to hook into function call is to use a trick with namespaces: Intercepting Execution of System Functions in PHP
You can also use the Go! framework to define an aspect to intercept the execution of system functions automatically.

Does function definition order matter?

In the script below, does the order in which items are declared matter?
For example, if the add_action points to a function that has not yet been defined? Does it matter or should the function declaration always precede any code in which its called?
add_action('load-categories.php', 'my_admin_init');
function my_admin_init(){
//do something
}
That doesn't matter if the function is declared before or after the call but the function should be there in the script and should be loaded in.
This is the first method and it will work:
some_func($a,$b);
function some_func($a,$b)
{
echo 'Called';
}
This is the second method and will also work:
function some_func($a,$b)
{
echo 'Called';
}
some_func($a,$b);
From the PHP manual:
Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below.
However, while this is more of a personal preference, I would highly recommend including all the functions you actually use in an external functions.php file then using a require_once() or include_once() (depending on tastes) at the very top of your main PHP file. This makes more logical sense -- if someone else is reading your code, it is blindingly obvious that you are using custom functions and they are located in functions.php. Saves a lot of guesswork IMO.
you can call a function before it's defined, the file is first parsed and then executed.
No.
It is not C :P...
As you can see here , the whole file is first being parsed and then executed.
If a function that doesn't exist is being called, php will throw an error.
Fatal error: Call to undefined function
As per my personal experience, In some special cases (Like, passing array's in function or function inside a function and so on). It's best option to define the function above the call. Because of this sometimes neither function works nor PHP throw an error.
In normal php functions, it doesn't matter. You can use both of the types.
It does not matter, as long as it is declared somewhere on the page.
as seen here:
http://codepad.org/aYbO7TYh
Quoting the User-defined functions section of the manual :
Functions need not be defined before
they are referenced, except when a
function is conditionally defined
So, basically : you can call a function before its definition is written -- but, of course, PHP must be able to see that definition, when try to call it.

Create a PHP Class Outline

I am looking for a function or class that can effectively outline a class:
class MyClass{
/*
* Perhaps include the function comments
* in the function.
*/
function mainFunction(){
//Does Something
}
function functionWithArgs($arg1,$arg2=false){
//Does Something
//The function I want will give e the arguments w/default values
}
}
Is there a function or library in existence that can give me some kind of access to the information about this class, or even the file.
ex.
get_file_outline('fileWithAboveClass.php');
or
get_class_outline('MyClass');
Does anybody know of either, or know a way of easily writing this?
Take a look at the PHP Reflection API
//use the ReflectionClass to find out about MyClass
$classInfo = new ReflectionClass('MyClass');
//then you can find out pretty much anything you want to know...
$methods = $classInfo->getMethods();
var_dump($methods);
//you can even extract your comments, e.g.
$comment=$classInfo->getMethod('mainFunction')->getDocComment();
Note that for the comment extraction to work, they have to be formatted like PHPDoc / Doxygen comments, and begin with an opening /**
There's also a command line option available for inspecting functions and classes.
$ php --rc DateTime
will give you all the details about the DateTime-class, while
$ php --rf in_array
will give you the arguments of the "in_array" function.
If you're using the Terminal when coding it can be quite handy to use instead of looking it up in the PHP Manual all the time ;)

PHP: Get argument count

This was incredibly surprising to see that PHP has no obvious function to do what I'm looking for, so I'll ask here.
How would you go about getting the number of arguments a particular function has outside of the function (just like func_num_args only from outside the function).
The solution can't actually execute the function (that would be defeating the purpose), and I'd like to do it (preferably) without any sort of reflection class.
Possible?
Oh, you can use the ReflectionFunction class, which inherits from ReflectionFunctionAbstract, which defines the getNumberOfParameters function:
$func_reflection = new ReflectionFunction('function_name');
$num_of_params = $func_reflection->getNumberOfParameters();
Note: This will only work on user functions, not class or instance functions.

Categories