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.
Related
I'm trying to sort an array based on the values within the array. I've tried the following
function comp($a, $b)
{
return strcmp($a["name"], $b["name"]);
}
in my functions class, but when call it from the same class
$usersInSection = $userManager->getUsersInSection($section);
usort($usersInSection, "conp");
i get the message
usort() expects parameter 2 to be a valid callback, function 'comp'
not found or invalid function name
If your comp is in a class then it's a method.
To use it in same class methods you need to call like this:
usort($usersInSection, array($this, "comp"));
The syntax to call usort with a callback inside a class is:
usort($usersInSection, array("MyClass", "comp"));
Check the PHP Manual: Callbacks / Callables
looks like you have a typo in usort($usersInSection, "conp"). your function is called comp not conp.
in my functions class
So you have a class to hold helper functions(?), and therefor comp is actually a method of that class?
Then you have to pass the class name or a class instance (for non-static method) to usort, in the same way as described in the manual for call_user_func_array.
When I have to write a reference to a callable function I use the standard syntax of PHP defined as:
A PHP function is passed by its name as a string. Any built-in or user-defined function can be used [... omitted...].
A method of an instantiated object is passed as an array containing an object at index 0 and the method name (aka string)
at index 1.
Static class methods can also be passed without instantiating an object of that class by passing the class name (still a string)
instead of an object at index 0.
As of PHP 5.2.3, it is also possible to pass (the string) 'ClassName::methodName'.
Apart from common user-defined function, anonymous functions can also be passed to a callback parameter.
All of these ways are not "IDE friendly" for operations like function name refactor or find usage of.
In my answer I propose a solution, but there are other approaches that can be applied, even totally different, that allow to IDE to "find" the invocation of the methods?
You already are next to the shortest thing you can do
You can perfectly call your anonymous function directly in your function call without using a variable
For instance, you can replace:
$callable=function($param) use ($object){
return $object->myMethod($param);
}
call_user_func($callable, $param);
by:
call_user_func(function($param) use ($object){
return $object->myMethod($param);
}, $param);
You will have to wait for arrow functions in future PHP versions, and you should be able to use something like:
call_user_func(fn($a) => $object->myMethod($a), $param);
I became to a solution, always based on the anonymous-functions that solve the problem but leave me not full satisfied:
Static method of a class
$callable = function($param){
return \my\namespace\myClass::myMethod($param);
}
method of a object
$callable = function($param) use ($object){
return $object->myMethod($param);
}
method of $this object
$callable = function($param){
return self::myMethod($param);
}
Alternatives for oldest php versions
Inside the all classess you gonna call (or in their parents) define the function classname() as follow:
public static function className()
{
return get_called_class();
}
or for very old PHP:
public static function className()
{
return "MyClass";
}
Then
call_user_func(array(MyClass::className(), 'myCallbackMethod'));
Im working lately on a custom mvc for php, and one of the question was really bothered me:
Ive got the controller class, and i want to check if a certain function of the class getting arguments, and if not, return false.
is there any method to do it?
cause i searched in php.net and google and didn't find anything....
thanx!
Use reflection:
$reflection = new ReflectionMethod ($class_name, $method_name);
$params = $r->getParameters();
$params is now an array of ReflectionParameter objects
Have a look at func_get_args
You can use it inside the method in your controller to get the list of all arguments passed to the method.
You also have func_num_args that will just give you the number of arguments passed to your method.
Use function func_get_args
function sum(){
$s=0;
foreach(func_get_args() as $a) $s+= is_numeric($a)?$a:0;
return $s;
};
print sum(1,2,3,4,5,6); // 21
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']);
I think about using the set_error_handler() functionality in PHP to handle most of the PHP errors in one place (logging them to a file). From the documentation it looks like if I can pass a function name to set_error_handler(). Nice! But I have an ErrorManager object which has a nice logging method. I want to use that ErrorManager object and write an special error handler method for it, and have set_error_handler call that ErrorManager.
Could I just do something like?:
set_error_handler($this->customErrorHandler);
Or would that be invalid?
Pass in an array of the object and the method name to be called:
set_error_handler(array($this, 'customErrorHandler'));
set_error_handler() takes a callback:
Some functions like call_user_func()
or usort() accept user-defined
callback functions as a parameter.
Callback functions can not only be
simple functions, but also object
methods, including static class
methods.
A PHP function is passed by its name
as a string. Any built-in or
user-defined function can be used,
except language constructs such as:
array(), echo(), empty(), eval(),
exit(), isset(), list(), print() or
unset().
A method of an instantiated object is
passed as an array containing an
object at index 0 and the method name
at index 1.
Static class methods can also be
passed without instantiating an object
of that class by passing the class
name instead of an object at index 0.
Apart from common user-defined
function, create_function() can also
be used to create an anonymous
callback function. As of PHP 5.3.0 it
is possible to also pass a closure to
a callback parameter.
(emphasis added)
In PHP 5.3 you could do it in a closure:
$that = $this;
set_error_handler( function() use ($that) { $that->customErrorHandler(); } );
set_error_handler accepts a callback as parameter.
Quoting that page :
A method of an instantiated object is
passed as an array containing an
object at index 0 and the method name
at index 1.
In your case, you want a callback that corresponds to a method (Called 'customErrorHandler') of an object (here, $this) ; the callback would then be :
array($this, 'customErrorHandler')
So, you'd use this portion of code :
set_error_handler(array($this, 'customErrorHandler'));