Strict standards error - php

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.

Related

Class member reference to another object in PHP

First code and then the question:
class MyArray
{
private $arrayRef;
function __construct(&$array){
$this->arrayRef = $array;
}
function addElement($newElement){
$this->arrayRef[] = $newElement;
}
function print(){
print_r($this->arrayRef);
}
}
$array = ['first', 'second'];
$arrayObject = new MyArray($array);
$arrayObject->addElement('third');
print_r($array); // prints array containing 2 elements
echo '<br/>';
$arrayObject->print(); // prints array containing 3 elements
Class member $arrayRef, in this example doesn't work as a reference to another array provided in constructor. Argument in constructor is passed by reference, but I guess that doesn't make member $arrayRef also a reference to that array as well.
Why doesn't it work like that and how to make it work?
If you still don't get what I mean: first print_r prints array containing 2 elements, even thought it may be expected to contain 3.
When I pass third element to $arrayObject via addElement() I also want it to be added in the $array that I passed to constructor of class.
The answer is actually quite simple. Yes, you pass the array by reference via &$array but this reference gets lost when you assign/copy it to the member variable. To keep the reference, you can use the =& operator like so
$this->arrayRef =& $array;
See it work in this fiddle. You can read more about it in this question/answer (just look for reference).
Beware not to use &= (which does a bitwise operation) instead of =& (which assigns by reference).

Accessing nested array's in Laravel view

Controller Code:
public function claims($id)
{
$claims = Claim::whereBetween('created_at', [
'2016-03-01',
'2016-03-31'
])->get();
return View::make('pdfs.view', $claims);
}
In my view I'm getting a message that $claims is an undefined variable.
I know that with a single array I can simply access the array properties by callig a variable of the same name. i.e. $claims['id] would simply by $id
However I cannot do this with a multidimensional array, as $claims does not exist
Also, I cannot pass the data as an object using ->with('claims' $claims) as I'm generating a PDF and the library does not support that function.
Any ideas how I can access the data?
Because your array doesn't contains that key
return View::make('pdfs.view', $claims);
instead you can use compact like as
return View::make('pdfs.view', compact('claims'));
Or you need to do it somewhat assigning your values to same key like as
$claims['claims'] = Claim::whereBetween('created_at', [
'2016-03-01',
'2016-03-31'
])->get();
return View::make('pdfs.view', $claims);
or you can simply use Laravels way using with variable like as
return View::make('pdfs.view')->withClaims($claims);
Note : While using compact make sure your variable name must matches your string

How to pass an array index in a function & check in a function either this index is set or not php

I have an associative array in php name as
$formData =array(
"first"=>"John",
"second"=>"George",
"thirld"=>"Harry",
"fourth"=>"Tom"
);
and a function called isExist($v) as
function isExist($v) {
if(isset($v)) {
return $v;
}
return "";
}
now I want that this function check either array have index value set or not i.e if I call the function as
echo isExist($formData['apple']);
then it must print an empty string. How to achieve this?
There is no way you can achieve this with passing $formData['apple'] you need to pass the array and index separately
function isExist($array,$index){
if(isset($array[$index])){
return $index;
}
return "";
}
The error will be raised before it ever had the chance to get in the function because you already called it when you were passing it in as parameter. Use it like this instead
isExist($formData,'apple');
There is already such a function. It's called.... drum roll
array_key_exists(string|int $key, array $array): bool
array_key_exists() returns true if the given key is set in the array. key can be any value possible for an array index.
https://www.php.net/manual/en/function.array-key-exists.php

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.

Passing an Array as Arguments, not an Array, in PHP

I seem to remember that in PHP there is a way to pass an array as a list of arguments for a function, dereferencing the array into the standard func($arg1, $arg2) manner. But now I'm lost on how to do it. I recall the manner of passing by reference, how to "glob" incoming parameters ... but not how to de-list the array into a list of arguments.
It may be as simple as func(&$myArgs), but I'm pretty sure that isn't it. But, sadly, the php.net manual hasn't divulged anything so far. Not that I've had to use this particular feature for the last year or so.
http://www.php.net/manual/en/function.call-user-func-array.php
call_user_func_array('func',$myArgs);
As has been mentioned, as of PHP 5.6+ you can (should!) use the ... token (aka "splat operator", part of the variadic functions functionality) to easily call a function with an array of arguments:
<?php
function variadic($arg1, $arg2)
{
// Do stuff
echo $arg1.' '.$arg2;
}
$array = ['Hello', 'World'];
// 'Splat' the $array in the function call
variadic(...$array);
// 'Hello World'
Note: array items are mapped to arguments by their position in the array, not their keys.
As per CarlosCarucce's comment, this form of argument unpacking is the fastest method by far in all cases. In some comparisons, it's over 5x faster than call_user_func_array.
Aside
Because I think this is really useful (though not directly related to the question): you can type-hint the splat operator parameter in your function definition to make sure all of the passed values match a specific type.
(Just remember that doing this it MUST be the last parameter you define and that it bundles all parameters passed to the function into the array.)
This is great for making sure an array contains items of a specific type:
<?php
// Define the function...
function variadic($var, SomeClass ...$items)
{
// $items will be an array of objects of type `SomeClass`
}
// Then you can call...
variadic('Hello', new SomeClass, new SomeClass);
// or even splat both ways
$items = [
new SomeClass,
new SomeClass,
];
variadic('Hello', ...$items);
Also note that if you want to apply an instance method to an array, you need to pass the function as:
call_user_func_array(array($instance, "MethodName"), $myArgs);
For sake of completeness, as of PHP 5.1 this works, too:
<?php
function title($title, $name) {
return sprintf("%s. %s\r\n", $title, $name);
}
$function = new ReflectionFunction('title');
$myArray = array('Dr', 'Phil');
echo $function->invokeArgs($myArray); // prints "Dr. Phil"
?>
See: http://php.net/reflectionfunction.invokeargs
For methods you use ReflectionMethod::invokeArgs instead and pass the object as first parameter.

Categories