call_user_func_array with variable name - php

suppose I need to use a variable's name as the function name of call_user_func_array()Docs
eg.
$j = new SomeObject();
and I'm trying to call $j->funcme();
call_user_func_array('$j->funcme()',$args);
returns the not found or invalid function name error
what should I do to rectify this?

Use it with an array for the Callback:
call_user_func_array(array($j, 'funcme'), $args);
See: call_user_func_arrayDocs

Related

Laravel passing array by reference to an event subscriber

Is it possible to pass an array by reference into an event subscriber?
I have an event "user.create.show" and I want to pass an array to the event so I could modify it if needed.
The call looks like this.
Event::fire('user.create.show', array($data));
The event subscriber looks like this.
public function createShow(&$data)
{
$data['foo'] = 'bar';
return $data;
}
I get a "Parameter 1 to UserSubscriber::createShow() expected to be a reference, value given" PHP error.
The line causing the error is the following:
return call_user_func_array($callable, $data);
I know I could return it the value, but Laravel returns an array with the variables and an multidimensional array if multiple variables were passed into the event. I could parse the return value but it would make my code a lot cleaner and easier if I could just pass by reference.
Well, using Event::fire('user.create.show', array($data)); you are clearly passing a value since you use array constructor in the call. Change it to the following:
$data = array($data);
Event::fire('user.create.show', $data);
Also pay attention to the notes here and to the solution of passing array by reference here.
This is how i pass by reference:
\Event::listen('foo', function(&$ref){
$ref = 'bar';
});
$foo = 'foo';
$args[] = &$foo;
\Event::fire('foo', $args);
echo $foo; // bar

Read the array inside the query scope

I have an array in $genreArr, i want it to be readable in the line whithin the function(query) inner select:
if($genreArr){
$movies = DB::table('movie_list')->whereIn('movie_id',function($query){
$query->select(DB::raw('movie_id'))
->from('movie_genre')
->whereIn('genre_id',$genreArr)
->distinct();
})->orderBy(DB::raw('RAND()'))->take(10)->get();
}
How do i do that without using global variables, i tried pass that variable as the second param next to the $query and than it gives me this kind of error:
Missing argument 2 for MovieController::{closure}()
You should adjust the closure to use the variable you want.
function ($query) use ($genreArr) {
... ->whereIn('genre_id', $genreArr);
}
Not sure whether the whereIn method will accept this. But rather than using a closure, you could use an alternative callable option. i.e Something like
$obj = new SomeClass();
$obj->setGenreArray($genreArr);
$movies = DB::table('movie_list')->whereIn('movie_id',array($obj, 'getQuery'))->orderBy(DB::raw('RAND()'))->take(10)->get();
And then you're query builder stuff will be inside the getQuery method, with access to the property $this->genreArray

PHP. Is there a way to require a function parameter to be an array?

Is there a way to require a function parameter is a specific datatype such as an array? For instance something like this:
function example(array $array){}
If so does that work for all datatypes? Is there a good resource that would show me how to do this?
Have a look at Type hinting http://php.net/manual/en/language.oop5.typehinting.php
Edit: Yes, you can type-hint with arrays, so edited my answer and changed accordingly.
What you want to do is called type-hinting. You can't type hint basic data types, such as int, string, bool. You can type-hint with array or objects and interfaces:
function example_hinted1(array $arr) {
}
function example_hinted2(User $user) {
}
Calling example_hinted1(5) will generate a PHP fatal error (not an exception), but calling it passing an array is totally ok.
If you need to be sure that some argument to a function is from a basic type you can simulate this behavior with code inside your function:
function example($number) {
if (!is_int($number) {
throw new Exception("You must pass an integer to ".__FUNCTION__."()");
}
// rest of your function
}
So, these snippets would work:
example(1);
$b = 5 + 8;
example($b);
while these would throw an exception:
example('foo');
example(array(5, 6));
example(new User());

php, I cant pass an array as reference

this is the function:
public function func(&$parameters = array())
{
}
now I need to do this:
$x->func (get_defined_vars());
but that fails. Another way:
$x->func (&get_defined_vars());
it drops an error: Can't use function return value in write context in ...
Then how to do it?
get_defined_vars() returns an array, not a variable. As you can only pass variables by reference you need to write:
$definedVars = get_defined_vars();
func($definedVars);
Though I don't really see a reason to pass the array by reference here. (If you are doing this for performance, don't do it, as it won't help.)
public function func(&$parameters = array())
{
}
Not defined correctly.
Try this way:-
call_user_func_array( 'func', $parameters );
See the notes on the call_user_func_array() function documentation for more information.

Strict standards error

The function parse_users returns an array.
I am doing the following in another function:
return reset($this->parse_users($records));
But I get a Strict Standards: Only variables should be passed by reference in...
Is it because I do a reset() on the function?
Do I have to do it this way:
$users = $this->parse_users($records);
return reset($users);
Or is something else?
That's it exactly. reset takes a reference to an array as a parameter, so it basically needs a real variable to reference -- even if it is a pass-by-reference value.
why didn't you try your
$users = $this->parse_users($records);
return reset($users);
?
It's correct
The one-line-solution uses an additional pair of brackets; this will turn the reference into a variable and omit the error:
return reset( ( $this->parse_users($records) ) );
From the PHP documentation for reset:
mixed reset ( array &$array )
reset() rewinds array's internal pointer to the first element and returns the value of the first array element.
The PHP reset() function accepts a reference to an array.
The strict warning is raised because you're directly passing the result of parse_users to reset, without a way to access that array in your other function.
If you're trying to return the full array (and not just the first value) after it's been reset, you should use:
$users = $this->parse_users($records);
reset($users);
return $users;
Alternatively, if you just want the first value from parse_users, you could just use:
$users = $this->parse_users($records);
return $users[0];
The reset function is only needed when you're iterating over the array and want to make sure you start from the beginning.

Categories