PHP, CallBack function - php

I am studying PHP and i am trying to understand about callback functions, I really looked around at the manual, At stackoverflow and more websites, And i really dont understand what is PHP CallBack Function , If can some one can please help me understand about this functions, I am looking for simple explanation/guide thank you all and have a nice day.

Take a look at Wikipedia - Callback
In computer programming, a callback is a reference to a piece of executable code that is passed as an argument to other code. This allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.
It's a function what you pass to your method or some other function, so it can be called later during that method - function execution.
For example you have callback beforeSave and you want do some logic before saving data to database file etc.. (in one place - DRY). You add logic into beforeSave callback and this callback being called before data saved.
Same is with function on manual for example array_filter($input, callback) it requires that you pass some function to be executed with $input data.
For ex. pass anonymous function:
array_filter($input, function($var) {
// returns whether the input integer is odd
return($var & 1)
});
Will return to you all odd array values, you can change logic in anonymous function to what you want, but array_filter internal mechanic will be always the same (iterator algo)

Related

php: what is the difference between functions getting their variables between brachets and using a $_session[variable] in a function?

I wondered what is the difference between
$x, $y, $z being variables declared and the function($x,$y,$z)
and
$_SESSION['x'], $_SESSION['y'],$_SESSION['z'] declared
and
function() using $_SESSION['x'], $_SESSION['y'], $_SESSION['z'];
Best regards, thanks.
In the first scenario, the values are provided to the function by whatever invokes that function. In the second, the function actively seeks out the variables from the session. The distinction between the two comes down to where the responsibility for finding the values should happen.
The session is a dependency. So if the function relies on the session, then the function has an internal dependency. This limits the versatility of the function.
If the function accepts the values as arguments, any PHP code anywhere can use the code in that function. If the function pulls the values from session state, then only an active web application can use that function. Plus that web application has to remember to put the values where the function can find them (since it doesn't advertise that it needs those values, as function arguments do).
In the majority of cases, the first approach is preferred. If the function performs an operation (and optionally returns a result), then have the function just do that. Have it "do one thing". The responsibility of providing the function with what it needs belongs to the code which calls the function. The function itself, as a fully-encapsulated entity, should simply advertise what it needs and what it is expected to return.

PHP How much memory does a function that only call another function like call_func(){func()} takes?

I have a function
function func(){ //somecode }
and function call_func(){ func(); }
so how much memory does call_function use?
and if I used many function like call_func_1() call_func_2() call func_3()
to call func() is it bad?
I got this question because this
I am using codeigniter framework,
In codeigniter if I have a controller php file named location.. and in that location controller, there is a function named index(),
Inside Index() function I have a code that receive get parameter that is used for searching something and output it as page..
so if i access www.something.com/location?city="Indonesia"&location="jakarta"
It will display the search result...
I wanted to make the link pretty by calling www.something.com/location/location_in_indonesia and the parameter I use Post
So in codeigniter if i used www.something.com/location/location_in_indonesia I will be calling a function named location_in_indonesia from location.php because I dont want to copy the code that do the search, I just use
function location_in_indonesia(){
$this->index()
//which called the function index and display the search result
}
and if i have another country to search then i need to add many function
But later after I posted this,I think this can be resolved by using routes feature that is provided by codeigniter. I was wondering about if it is bad to use that function that is just calling another function. So I asked this question.
When you call a function from within another function this is what happens (note this is a generic description and not really PHP specific).
The calling function will push its current state into the call stack which as the name implies, is a stack (meaning the status will be placed on the top). The information that gets pushed is (roughly speaking) the position within the function at which the function call happened and references to variables in scope.
Now this implies that the memory taken in the stack will basically be some constant + the number of variables in scope. In a programming language like C, the size that this stack can take up is pretty much constant and allocated by the OS, in Java you can specify this size via JVM parameters but more or less this means that there's a finite number of functions within functions that one can call (this is one of the reasons why there's so much research being done to convert recursive algorithms to iterative ones).
Now what this means for your case is that the extra memory required for the function call is just a pointer to where the calling function was when the call occurred, which is basically a very low price to pay.
Overall what you are doing is pretty common and I have no indication to believe that it's bad practice (although routing is probably better practice for your specific case).
Also, if you're using a PHP framework, then the extra cost of a single function call is very small compared to everything else that the framework is doing.

media wiki. how did function get argument?

The question is about functions and arguments in PHP. I am reading code of simple extension for mediawiki.
It adds callback function:
$wgHooks['ArticleSaveComplete'][] = 'fnAutoWikiDump';
and then there is definition of this function:
function fnAutoWikiDump(&$article, &$user, &$text, &$summary, &$minoredit,
&$watchthis, &$sectionanchor, &$flags, &$revision){...}
inside this function I can access members of class $article:
$awd_title = $article->getTitle();
I cannot understand how variable $article was passed to the function while calling it? It looks like it was passed in definition of the function (I know it is wrong), but I don't understand how it was passed.
Do you?
The code you have posted, and the sample code in the link do not show the details of actually calling the function. It is merely registered as a callback. Part of the usefulness of callback functions is that you typically do not have to call them yourself at all, but rather they are called automatically by the process that uses them.
Somewhere else in the MediaWiki code, where the callbacks registered with ArticleSaveComplete are called (there's an array of them), the correct parameters are passed to the function call in a regular and recognizable function call or via a mechanism like call_user_func().
When defining a callback to work with that interface, your responsibility as a programmer is only to be sure that the function definition takes the correct number of parameters in the correct order, and with the correct names. The details of how it gets called are up to the mechanism that calls it.

How can I decouple $_POST/$_GET handling code from html forms/urls? (PHP-OOP)

In a class I have a handling method which performs actions based on what post/get variables are available. Here is a simplified example:
public function handleAll(array $vars) {
if (isset($vars['var1'])) {
$this->doThisAction($vars['var1']);
} else if (isset($vars['var2'])) {
$this->doAnotherAction($vars['var2']);
}
}
So at runtime the method could be called like this $handler->handleAll($_POST).
The problem is that the variables stored in the $vars array must be named "var1" & "var2" etc. This means that the handling code is coupled with the names of html form elements or get variables in urls (or indeed the keys of any array passed in).
Allowing an array of any variables to be injected makes the method flexible which is necessary as it is also polymorphic. Classes inherit this method and use it to call it's own actions. A result of this is that it is not obvious from the outside what the handling method requires for it to function. This means that the implementation must be examined to find out what it does (unless I copy the code into the phpdoc which would be silly).
I'm not sure how to get around this. Having enormous if/case statements all exposed on index pages (from multiple classes like these) makes for extremely messy code so it is preferable to have all this encapsulated within a method. Also, it makes sense to have it as a method of the class responsible for calling the actions that manipulate it's own state (responsibility driven design). I thought about having each variable as a parameter for the method but for some classes the parameter list would be quite large. Also it would mean that many handleAll() methods of different classes cannot be called automatically as all parameters would need to be explicitly injected for each call, removing the polymorphic aspect.
To sum up I need to keep the method polymorphic but I need some way of decoupling the handling code from user input from html forms or urls. In doing this perhaps there is a way of separating the interface from the implementation too. I'm surprised I can't find any solutions to this already, it seems like it would be a common problem.
I'm not sure if what you describe can even be avoided.
If you have code which requires specific arguments to it - be it in the form of an array containing certain values or whatever else - that function will always depend on the arguments being populated correctly.
If I have function foo($a, $b, $c), I will always have to fill the parameters. If they come from POST, then I would need to take them from POST. The same goes even if the function took an array('a' => ..., 'b' => ..., 'c' => ...) instead.
However, if you wanted to decouple your forms from the parameter list, you could use a simple function to transform the POST array into the format expected by one of your handler functions. I do not really see any reason for this though, since why add the extra complexity if you don't have to?
If you wish to better define what kind of array your handler requires, you could consider having it require an object instead. This approach is sometimes called a parameter object.
The benefits of using a parameter object is that you can easily set up required parameters in the constructor, and use setters for optional ones. Anyone who uses your code can just look at your object's interface to see what values are required.
If the values your handlers use are actually related to each other, I would consider creating an actual business logic type object. Create it using the data from POST, and move the code which processes the values into a method in the object.
Decoupling and automating handling methods, can be painful methods to narrow down too. But there is not so many options, other than, create handlers for eveything. However, I would you like add something. Allow defaults and support variation
function handlePOST() { }
function handleGET() { }
function handleArr() { }
Now, these function can hold the variations of the function on their behalf.
Inside however, they is not better way other than to code all the handlers. But switch is shorten them and use separate function for the handling.
switch($_POST['var1']) {
case "value1": callPostValue1(); break;
default: callPostDefaultHandler(); break;
}

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.

Categories