Setting callback function in array_map giving error - php

class Test
{
public $callback = "sqrt";
public function cube($n)
{
return($n * $n * $n);
}
public function cool()
{
$a = array(1, 2, 3, 4, 5);
$b = array_map( $this->callback , $a);
var_dump($b);
}
}
$t = new Test();
$t->cool();
In this code if $callback is set to something like intval or sqrt then it will work fine , but when i try to use cube method as callback function it is giving following error. Why so
and how to call method cube from cool method as callback

In PHP, you can use an array to associate an object and a method call as a callable
array_map(array($this, $this->callback), $array);
http://php.net/manual/en/language.types.callable.php

Try this:
$b = array_map( array($this, $this->callback) , $a);
Output is:
array
0 => int 1
1 => int 8
2 => int 27
3 => int 64
4 => int 125
If its a static method:
$b = array_map( "Test::staticMethodName" , $a);
UPDATE:
Ok, the problem is, when you giving this parameter to your array_map, it parse, what's in the property of your class called callback. There is a string value: cube. You have no global cube function. intval and sqrt are global functions, so they will work. So you need to pass as the PHP documents says: A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.
This is why my example works, because you have an instantiated method $this, and the method name in $this->callback.
And for static methods:
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. As of PHP 5.2.3, it is also possible to pass 'ClassName::methodName'.

Try this
$b = array_map(array($this, 'cube'), $a);
instead of
$b = array_map( $this->callback , $a);

Related

How to use a PHP associative array as function call arguments? [duplicate]

This question already has answers here:
Does PHP allow named parameters so that optional arguments can be omitted from function calls?
(17 answers)
Closed 6 months ago.
Assume that there is a function with some parameters and I have an associative array (or a simple object with public properties - which is almost the same, since I can always use a type cast (object)$array) whose keys correspond to the function parameter names and whose values correspond to function call arguments. How do I call it and pass them in there?
<?php
function f($b, $a) { echo "$a$b"; }
// notice that the order of args may differ.
$args = ['a' => 1, 'b' => 2];
call_user_func_array('f', $args); // expected output: 12 ; actual output: 21
f($args); // expected output: 12 ; actual output: ↓
// Fatal error: Uncaught ArgumentCountError:
// Too few arguments to function f(), 1 passed
It turns out, I just had to use variadic function named param unpacking feature introduced in PHP 8 ( https://wiki.php.net/rfc/named_params#variadic_functions_and_argument_unpacking ) :
f(...$args); // output: 12
Prior to PHP 8, this code produces the error: Cannot unpack array with string keys.
Secondly, it turns out that call_user_func_array also works as expected in PHP 8 (see https://wiki.php.net/rfc/named_params#call_user_func_and_friends for explanation):
call_user_func_array('f', $args); // output: 12
- while it still outputs incorrect '21' in older versions.
As a hack for older versions of PHP you could also use Reflection:
<?php
function test($b, $a) {
echo "$a$b";
}
$callback = 'test';
$parameters = ['a' => 1, 'b' => 2];
$reflection = new ReflectionFunction($callback);
$new_parameters = array();
foreach ($reflection->getParameters() as $parameter) {
$new_parameters[] = $parameters[$parameter->name];
}
$parameters = $new_parameters;
call_user_func_array($callback, $parameters);
Demo

Php | How to pass unknown length array of arguments to function individually

I have an array of arguments that are in order for a function.
The number of items in the array differ. I want to be able to pass in each item in the array individually to the functions (eg...func(arg1, arg2, arg3, arg4);). Opposed to just passing in the whole array.
Keep in mind, I do not know the length of the array, it differes depending on which function I am calling.
since PHP 5.6 you have the Variable-length argument lists so you can call your function like this:
$arr = array(1, 2, 5, "ten");
and you can send all the elements in the $arr to a function by calling it like this:
myFunc(...$arr);
If you mean you have a function that its argument is an array, you can use foreach to fetch all the array elements:
function my_func($arg_array)
{
foreach($arg_array as $key=>$value)
{
......
}
....
}
But if you mean you have a function that has unknown number of arguments you can use func_get_args function that returns an array containing arguments as an array.
function my_func()
{
foreach(func_get_args() as $key=>$value)
{
......
}
....
}
Use : call_user_func_array("functionName", $arrayofArgs);
<?php
function unknown($arg1,$arg2,$arg3){
echo "arg1 = $arg1 <br>";
echo "arg1 = $arg2 <br>";
echo "arg1 = $arg3 <br>";
}
$array = [
"arg1" => "Hi",
"arg2" => "Marhaba",
"arg3" => "Hola",
"arg4" => "foo"
];
call_user_func_array("unknown", $array);
?>
and you can call the function from class by passing the first param as array of ["className","methodName"]
php Docs :
http://php.net/manual/en/function.call-user-func-array.php
In PHP you have:
func_num_args()
func_get_args()
func_get_arg()
for that purpose.
EDIT
If you are fine using PHP 5.6 then you have splat operator. Quoting sample from docs (link):
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$operators = [2, 3];
echo add(1, ...$operators);

Best way to emulate Ruby "splat" operator in PHP function signatures [Method overloading]

In Ruby
def my_func(foo,bar,*zim)
[foo, bar, zim].collect(&:inspect)
end
puts my_func(1,2,3,4,5)
# 1
# 2
# [3, 4, 5]
In PHP (5.3)
function my_func($foo, $bar, ... ){
#...
}
What's the best way to to do this in PHP?
Copying my answer from another question related to this:
This is now possible with PHP 5.6.x, using the ... operator (also
known as splat operator in some languages):
Example:
function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
foreach ( $intervals as $interval ) {
$dt->add( $interval );
}
return $dt;
}
Try
func_get_args — Returns an array comprising a function's argument list
PHP Version of your Ruby Snippet
function my_func($foo, $bar)
{
$arguments = func_get_args();
return array(
array_shift($arguments),
array_shift($arguments),
$arguments
);
}
print_r( my_func(1,2,3,4,5,6) );
or just
function my_func($foo, $bar)
{
return array($foo , $bar , array_slice(func_get_args(), 2));
}
gives
Array
(
[0] => 1
[1] => 2
[2] => Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
)
)
Note that func_get_args() will return all arguments passed to a function, not just those not in the signature. Also note that any arguments you define in the signature are considered required and PHP will raise a Warning if they are not present.
If you only want to get the remaining arguments and determine that at runtime, you could use the ReflectionFunction API to read the number of arguments in the signature and array_slice the full list of arguments to contain only the additional ones, e.g.
function my_func($foo, $bar)
{
$rf = new ReflectionFunction(__FUNCTION__);
$splat = array_slice(func_get_args(), $rf->getNumberOfParameters());
return array($foo, $bar, $splat);
}
Why anyone would want that over just using func_get_args() is beyond me, but it would work. More straightforward is accessing the arguments in any of these ways:
echo $foo;
echo func_get_arg(0); // same as $foo
$arguments = func_get_args();
echo $arguments[0]; // same as $foo too
If you need to document variable function arguments, PHPDoc suggest to use
/**
* #param Mixed $foo Required
* #param Mixed $bar Required
* #param Mixed, ... Optional Unlimited variable number of arguments
* #return Array
*/
Hope that helps.

PHP: Array to variable function parameter values

I have a variable length array that I need to transpose into a list of parameters for a function.
I hope there is a neat way of doing this - but I cannot see how.
The code that I am writing will be calling a method in a class - but I will not know the name of the method, nor how many parameters it has.
I tried this - but it doesn't work:
$params = array(1 => "test", 2 => "test2", 3 => "test3");
ClassName::$func_name(implode($params, ","));
The above lumps all of the values into the first parameter of the function. Whereas it should be calling the function with 3 parameter values (test, test2, test3).
What I need is this:
ClassName::$func_name("test", "test2", "test3");
Any ideas how to do this neatly?
Yes, use call_user_func_array():
call_user_func_array('function_name', $parameters_array);
You can use this to call methods in a class too:
class A {
public function doStuff($a, $b) {
echo "[$a,$b]\n";
}
}
$a = new A;
call_user_func_array(array($a, 'doStuff'), array(23, 34));
You could use eval:
eval("$func_name(" . implode($params, ",") . ");");
Though you might need to do some lambda trickery to get your parameters quoted and/or escaped:
$quoted_escaped_params = array_map(create_function('$a', 'return "\"". str_replace("\"",` "\\\"", $a) . "\""'), $params);

How to pass variable number of arguments to a PHP function

I have a PHP function that takes a variable number of arguments (using func_num_args() and func_get_args()), but the number of arguments I want to pass the function depends on the length of an array. Is there a way to call a PHP function with a variable number of arguments?
If you have your arguments in an array, you might be interested by the call_user_func_array function.
If the number of arguments you want to pass depends on the length of an array, it probably means you can pack them into an array themselves -- and use that one for the second parameter of call_user_func_array.
Elements of that array you pass will then be received by your function as distinct parameters.
For instance, if you have this function :
function test() {
var_dump(func_num_args());
var_dump(func_get_args());
}
You can pack your parameters into an array, like this :
$params = array(
10,
'glop',
'test',
);
And, then, call the function :
call_user_func_array('test', $params);
This code will the output :
int 3
array
0 => int 10
1 => string 'glop' (length=4)
2 => string 'test' (length=4)
ie, 3 parameters ; exactly like iof the function was called this way :
test(10, 'glop', 'test');
This is now possible with PHP 5.6.x, using the ... operator (also known as splat operator in some languages):
Example:
function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
foreach ( $intervals as $interval ) {
$dt->add( $interval );
}
return $dt;
}
addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ),
new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );
In a new Php 5.6, you can use ... operator instead of using func_get_args().
So, using this, you can get all the parameters you pass:
function manyVars(...$params) {
var_dump($params);
}
Since PHP 5.6, a variable argument list can be specified with the ... operator.
function do_something($first, ...$all_the_others)
{
var_dump($first);
var_dump($all_the_others);
}
do_something('this goes in first', 2, 3, 4, 5);
#> string(18) "this goes in first"
#>
#> array(4) {
#> [0]=>
#> int(2)
#> [1]=>
#> int(3)
#> [2]=>
#> int(4)
#> [3]=>
#> int(5)
#> }
As you can see, the ... operator collects the variable list of arguments in an array.
If you need to pass the variable arguments to another function, the ... can still help you.
function do_something($first, ...$all_the_others)
{
do_something_else($first, ...$all_the_others);
// Which is translated to:
// do_something_else('this goes in first', 2, 3, 4, 5);
}
Since PHP 7, the variable list of arguments can be forced to be all of the same type too.
function do_something($first, int ...$all_the_others) { /**/ }
For those looking for a way to do this with $object->method:
call_user_func_array(array($object, 'method_name'), $array);
I was successful with this in a construct function that calls a variable method_name with variable parameters.
You can just call it.
function test(){
print_r(func_get_args());
}
test("blah");
test("blah","blah");
Output:
Array ( [0] => blah ) Array ( [0] => blah [1] => blah )
I'm surprised nobody here has mentioned simply passing and extracting an array. E.g:
function add($arr){
extract($arr, EXTR_REFS);
return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3
Of course, this does not provide argument validation.
For that, anyone can use my expect function: https://gist.github.com/iautomation/8063fc78e9508ed427d5
I wondered, I couldn't find documentation about the possiblity of using named arguments (since PHP 8) in combination with variable arguments. Because I tried this piece of code and I was surprised, that it actually worked:
function myFunc(...$args) {
foreach ($args as $key => $arg) {
echo "Key: $key Arg: $arg <br>";
}
}
echo myFunc(arg1:"foo", arg2:"bar");
Output:
Key: arg1 Arg: foo
Key: arg2 Arg: bar
In my opinion, this is pretty cool.
Here is a solution using the magic method __invoke
(Available since php 5.3)
class Foo {
public function __invoke($method=null, $args=[]){
if($method){
return call_user_func_array([$this, $method], $args);
}
return false;
}
public function methodName($arg1, $arg2, $arg3){
}
}
From inside same class:
$this('methodName', ['arg1', 'arg2', 'arg3']);
From an instance of an object:
$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])
An old question, I know, however, none of the answers here really do a good job of simply answer the question.
I just played around with php and the solution looks like this:
function myFunction($requiredArgument, $optionalArgument = "default"){
echo $requiredArgument . $optionalArgument;
}
This function can do two things:
If its called with only the required parameter: myFunction("Hi")
It will print "Hi default"
But if it is called with the optional parameter: myFunction("Hi","me")
It will print "Hi me";
I hope this helps anyone who is looking for this down the road.

Categories