php, I cant pass an array as reference - php

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.

Related

How to receive specific interface's array in PHP class method?

I want to receive array of MyInterface as the in the below code.
public function saveMultiple(
\Path\To\MyInterface $attachLinks[]
);
The above code doesn't work.
So please don't tell me that just remove \Path\To\MyInterface and to use a variable $attachLinks. I'm already aware of that but this is something which I require.
There are no generic types in php, so you can not specify type «array of something».
But you may do a trick. Check types of elements in array.
array_walk($attachLinks, function (\Path\To\MyInterface $item) {});
If you wrap it in assert, you will be able to disable this check.
assert('array_walk($attachLinks, function (\Path\To\MyInterface $item) {})');
So far this is what can be done using PHP7. Till date passing arrays with specific type is not possible.
public function saveMultiple(
array $attachLinks
);
It'll now at least make sure that the method only gets array as parameter.
Maybe you can use some type of setter like:
private $attachLinks = [];
public function setter(MyInterface $var)
{
$this->attachLinks[] = $var;
}
And than use a $this->attachLinks in your function
public function saveMultiple() {
print_r($this->attachLinks);
}

Using a function in php - what am I doing wrong?

$users = [
"Andrew",
"Max",
"Larry",
"Ricardo",
"Lucy",
"Marcus",
"Sophie"
];
$sector_rel = [];
$location_rel = [];
function sectorRel($user){
return sector_rel[] = round(1/rand(1,10),3);
}
function locationRel($user){
return $location_rel[] = round(1/rand(1,20),3);
}
foreach($users as $user){
sectorRel($user);
locationRel($user);
}
This:
function sectorRel($user){
return sector_rel[] = round(1/rand(1,10),3);
}
Should be/could be:
function sectorRel($user){
global sector_rel;
sector_rel[] = round(1/rand(1,10),3);
}
The problem is that the functions don't have access to the array variables. You can import them into the function scope using the keyword global, if they are indeed global variables. Now, having global variables isn't a good thing, and for a small test it's okay, but eventually you'll be eliminating your globals and this solution won't work.
But alternatively, you could pass the array variables to the function as an argument. However, this still introduces a lot of logic in the function. The function has to be told about the array, it must know that it needs to add a value to the end, and it also needs to calculate the actual value to add.
So better, make the function just return the calculated value and add it to the array outside of the function:
function sectorRel($user){
// Assuming your are going to use 'user' here somewhere?
return round(1/rand(1,10),3);
}
function locationRel($user){
return round(1/rand(1,20),3);
}
foreach($users as $user){
sector_rel[] = sectorRel($user);
$location_rel[] = locationRel($user);
}
You can then wrap this entire snippet of code into another function and call that to populate the arrays. That way, you've quite reasonably split the responsibilities of the functions and have a piece of code that looks nice and clean.
You do not need to use return in either of sectorRel or locationRel. At the moment this will return the reference to that array and it is not being stored in a variable. You would need to store them in a variable or just get rid of the return. My PHP is a little weak at the moment but you should probably append the values in those functions to the array.
Also if you have a parameter called $user for each of those functions you should either use that parameter or just get rid of it.

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

Wrapper method for mysqli_bind_param

I'm writing a Database wrapper class and need something like:
public function bind($types, $params, ...) {
$this->prep->bind_param($types, $params, ...);
}
How can I make the arguments dynamic, to have N-params?
I know of the function func_get_args() but doesn't help, I can fetch the arguments, but how to pass?
Off the top of my head, you could do it using call_user_func_array():
public function bind() {
$args=func_get_args();
$method=array($this->prep,'bind_param');
call_user_func_array($method,$args);
}
The function call_user_func_array should be what you need, something along the lines of the following:
public function bind () {
$args = func_get_args();
call_user_func_array(array($this->prep, "bind_param"), $args);
}
call_user_func and call_user_func_array can sometimes be a little slower than calling a method directly, unfortunately there isn't much you can do about this apart from hard code in the first few arguments.
Use an array, i advise you to use the classic way and keep some "core" arguments away from the array, than you can put optionnal ones in an array like so:
function function(Class $object, array $options = array()){
}

php use array as array_map first argument

I can't kind of make out the first return statement, can anybody help to explain how it works?
the array_map accept a function for the first arg, but here is an array. and how does array(&$this, '_trimData') work? thanks for explaining.
private function _trimData($mParam)
{
if (is_array($mParam))
{
return array_map(array(&$this, '_trimData'), $mParam);
}
$mParam = trim($mParam);
return $mParam;
}
This is a recursive function. _trimData calls itself if the parameter passed to it was an array.
array(&$this, '_trimData') is a callback to the current object's method _trimData.
The entire method could really be replaced with:
private function _trimData($mParam)
{
array_walk_recursive($mParam, 'trim');
return $mParam;
}
It is callback: $this->_trimData() (_trimData of object $this)
A bit further of an explanation about how array(&$this, '_trimData') acts as a callback, despite looking like an array:
A PHP function is passed by its name as a string... A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1. PHP: Callbacks/Callables
So in this case, the object is &$this and the method is _trimData, and making it into an array is one way PHP allows you to pass it as a callback into array_map.

Categories