views:

97

answers:

4
$test = 'love';
$eff = end(explode('ov',$test));

I can't figure it out; oddly enough, this doesn't get a complain:

$test = 'love';
$eff = current(explode('ov',$test));

The error I'm getting is: Strict: Only variables should be passed by reference

+2  A: 

The explode returns a temporary array, which you are not 'storing' to a variable but rather passing directly to end which expects a reference.

I believe the reason why current does not trigger the error is that it is non-mutating. Other mutating functions such as array_unshift and reset complain too.

p00ya
`current` expects reference as well. that's the thing.
thephpdeveloper
see edits, I think it's because of the read-only thing.
p00ya
A: 
<?php

error_reporting(E_STRICT);

$test = 'love';
$eff = end(explode('ov',$test));
var_dump($eff);

?>

it will work fine if your error reporting level is not set to E_STRICT.

See, when you have an temporary array returned, you cannot just set the internal pointer just like this. You need to set it to a variable first then move the internal pointer to the end using end().

This is true so for: reset(), next(), prev() and so on.

The following would work instead.

<?php

error_reporting(E_STRICT);

$test = 'love';
$a = explode('ov',$test);
$eff = end($a);
var_dump($eff);

?>

current() works because it does not move the internal pointer, but to get what the current element that the internal pointer is pointing at.

thephpdeveloper
You'll get the errors when you use ``error_reporting(E_STRICT)`` in PHP 5.x, too. E_STRICT is only a subset of E_ALL under PHP 6.x.
p00ya
Whether `E_STRICT` is a subset of `E_ALL` varies quite a bit depending on PHP version, I think. It wasn't and then it was and then it wasn't again. But you never want to set `error_reporting` to `E_STRICT` alone. You want to OR it together with `E_ALL` (`error_reporting(E_ALL | E_STRICT);`), otherwise you're going to miss important non-strict errors. If `E_STRICT` is contained in `E_ALL` it won't do any harm to OR it in anyway.
Ollie Saunders
+5  A: 

end changes the array's internal pointer by moving it to the end of the array. Thus, the parameter must be mutable (that is, a reference to an array) for that operation to be useful. This is why you receive the warning.

current doesn't touch the array at all; it only looks at the array. Thus, the parameter does not need to be mutable (thus can be passed by value) and the operation doesn't give you a warning.

strager
+2  A: 

end() modifies the array passed to it, by reference. Assign the explosion to a variable first so that end() has a reference it can modify.

$test = 'love';
$explosion = explode('ov',$test);
$eff = end($explosion);

end() only changes an internal pointer so it doesn't modify the contents of the array in anyway and you won't notice unless you're using the current(), each(), next() lot for iteration.

If this limitation of end() is annoying to you there are ways around it:

function last($array) { return end($array); }
$test = 'love';
$eff = last(explode('ov', $test));
Ollie Saunders