pass a callback WITH arguments in PHP - php

I have a PHP library function expecting a callback with no arguments.
I know I can pass an object's method with array($this , 'my_function_name') but how can I give parameters to the my_function_name?
I have found a solution using create_function but from PHP manual I see it has security issues.

$that = $this;
$wrapper = function() use($that) {
return $that->my_function_name('arg1', 'arg2');
};

There is a function called call_user_func_array.
call_user_func_array([$this, 'method'], $args);

This will depend on your library functions initiation of the callback method. You mentioned that you're making a wordpress theme. WP uses the call_user_func method typically. In your library function, use this function to invoke a call back with args, wrap a methods argument when calling it:
Callback Definition:
$callbackArg = "Got here";
defined_lib_func(array($this , 'my_function_name'), $callbackArg);
Library Script:
function defined_lib_function($callback, $args) {
call_user_func($callback, $args);
}
for multiple arguments, just pass them as an array and define your callback method to accept an array as an argument.

Related

PHP - Alternatives on passing variables to function using ...[array] in php 5.4

Is there an alternative function or way to pass variable inside function like
how php 5.6 does using "..."?
Ex:
function(...[$a, $b])
you can find this at example #7 on this link
I'm currently running a 5.4.4 (to be exact) environment and a bit scared of upgrading it.
--- sample code
$query->myFunction($var1, $var2, function($va1, $var2, $class){
$class->anotherFunction($var1, $var2);
});
-- inside query builder
function myFunction($var1, $var2, $callback = null){
$callback($var1, $var2, $this);
}
$callback - i want this callback function to be filled with variables automatically no matter how many i pass in it.. as what i said on #7 example.. that function will help me do this, and i'm searching for an alternative
It's not exactly the same, but you can get the arguments into an array with func_get_args and then process it from there.
http://php.net/manual/en/function.func-get-args.php
If you want the function to receive the callback plus other arguments, you can use this:
function foo() {
$args = func_get_args();
$callback = array_pop($args);
}
You now have $args with all function parameters before the final $callback. In order to call that callback, you need another related function:
call_user_func_array($callback, $args);
Study the documentation for those functions, they have a lot of rare and surprising "features" that you should be aware of.
As I understood your query, I suggest you to use following functions -
http://php.net/manual/en/function.func-get-arg.php
http://php.net/manual/en/function.func-get-args.php
http://php.net/manual/en/function.func-num-args.php

Have $this in PHP implicit function before PHP 5.4.0

According to http://php.net/manual/en/functions.anonymous.php, in PHP 5.3 $this is not accessible from inside an implicit function, even if the function is defined in a context where $this exists. Is there any way to work around this limitation? (by the way, upgrading the PHP installation on the webserver is not possible)
The way I would like to use the implicit function is to define a callback which is a member function of some object. More precisely, I would like to do something like
$callback = function() { return $this->my_callback(); }
Actually, an event better syntax would be
$callback = $this->my_callback
but I cannot make it work (PHP dies with "Fatal error: Function name must be a string" when I try to execute the callback).
Should do the work:
$object = $this ;
$callback = function() use ($object) { return $object->my_callback(); } ;
use will bring an accessible variable (in our case the reference of the object) upon its declaration to the function scope, so you will not have to send it as a parameter.
Sometimes it is even better to use such a varname as $self or $that so to be more clear.
$function = array($this, 'my_callback');
(perhaps combined with call_user_func() )
It looks like you can pass variables to the callback function. I haven't worked with closures in PHP, but I think this would work for you:
$callback = function($instance) { return $instance->my_callback(); }
$callback($this);
Or if the callback is triggered outside the current class.
$callback($myClassInstance);

How to use a static method as the callback parameter in preg_replace_callback()?

I'm using preg_replace_callback to find and replace textual links with live links:
http://www.example.com
to
<a href='http://www.example.com'>www.example.com</a>
The callback function I'm providing the function with is within another class, so when I try:
return preg_replace_callback($pattern, "Utilities::LinksCallback", $input);
I get an error claiming the function doesn't exist. Any ideas?
In PHP when using a class method as a callback, you must use the array form of callback. That is, you create an array the first element of which is the class (if the method is static) or an instance of the class (if not), and the second element is the function to call. E.g.
class A {
public function cb_regular() {}
public static function cb_static() {}
}
$inst = new A;
preg_replace_callback(..., array($inst, 'cb_regular'), ...);
preg_replace_callback(..., array('A', 'cb_static'), ...);
The function you are calling of course has to been visible from within the scope where you are using the callback.
See http://php.net/manual/en/language.pseudo-types.php(dead link), for details of valid callbacks.
N.B. Reading there, it seems since 5.2.3, you can use your method, as long as the callback function is static.
You can do it like this:
return preg_replace_callback($pattern, array("Utilities", "LinksCallback"), $input)
Reference: http://php.net/callback
You can also use T-Regx library:
pattern($pattern)->replace($input)->callback([Utilities::class, 'LinksCallback']);

PHP Callback function not working on object functions

I have an array and want to apply MySQLi->real_escape_string on every member of the array through array_walk but this is not working:
array_walk($array, '$mysqli->real_escape_string');
It gives this error:
Warning: array_walk() expects parameter 2 to be a valid callback, function '$mysqli->real_escape_string' not found or invalid function name in C:\wamp\www\ts.php on line 69
$mysqli is a valid object and works fine if I do $mysqli->real_escape_string('anything') on anything else.
My Question: Is it not possible to pass object's functions as callback ? Or am I doing something wrong.
IMPORTANT: I know I can create my own callback function and implement $mysqli->real_escape_string in it BUT I want to know is it not possible to use callback as an object's function ?
If your calling a method within an object you should pass in an array, first item being the object / context and then second should be the method:
Small example
function callback()
{
//blah
}
the above is called a function and should be called like so: array_walk($array, 'callback');
class object()
{
public function callback()
{
}
}
the above callback is called a method, its practically the same as a function but because its within a class it has a parent context, so should be called like so:
$object = new object();
array_walk($array, array($object , 'callback'));
MySQLi is an object orientated library so after you have initialized your mysqli object you should call the "method" like so:
array_walk($array, array($msqli, 'real_escape_string'));
Also as mentioned above, array_walk will walk both key and value into the mysql object witch will cause in exact escaping, you should use array_map to walk the values alone:
array_map($array, array($msqli, 'real_escape_string'));
As you can read on php callback page, you shall use:
# produces an error
array_walk($array, array($msqli, 'real_escape_string'));
array_map($array, array($msqli, 'real_escape_string'));
array_walk will only allow a user defined function to be passed as the callback, not a core PHP function or method. To do this I would try the following:
foreach($array as &$value) {
$value = $mysqli->real_escape_string($value);
}
Passing the value by reference allows it to be modified within the foreach loop, resulting in each member of the array being escaped.
I found this post to be quite useful when figuring out how to get array_walk() to work in methods within a class. Adding it to this thread in case it helps others out.

PHP, how to pass func-get-args values to another function as list of arguments?

I want to create a function (my_function()) getting unlimited number of arguments and passing it into another function (call_another_function()).
function my_function() {
another_function($arg1, $arg2, $arg3 ... $argN);
}
So, want to call my_function(1,2,3,4,5) and get calling another_function(1,2,3,4,5)
I know that I shoud use func_get_args() to get all function arguments as array, but I don't know how to pass this arguments to another function.
Thank you.
Try call_user_func_array:
function my_function() {
$args = func_get_args();
call_user_func_array("another_function", $args);
}
In programming and computer science, this is called an apply function.
Use call_user_func_array
like
call_user_func_array('another_function', func_get_args());
It's not yet documented but you might use reflection API, especially invokeArgs.
(maybe I should have used a comment rather than a full post)
I have solved such a problem with the ...$args parameter in the function.
In my case, it was arguments forwarding to the parent construction call.
public function __construct(...$args)
{
parent::__construct(...$args);
}

Categories