So I have this slightly annoying issue: say I have a foreach loop like this:
foreach ($arr as $key=>$value) {
do_something($key);
}
In my eclipse environment, I have turned on the feature that displays warnings for unused variables, which is really helpful. However, it complains for all such occurences, where the $value is not used in the loop.
I was wondering if there is some syntax where I don't use this, like is available for list() :
list(,,$my_var) = some_func();
//these returns an array with 3 elements, but I only need the last one
Note: The obvious would be to use array_keys(), but I don't want a function call; I'm merely asking if there's a shorthand I don't know of, or something like it. This is why the question PHP foreach that returns keys only does not cover what I'm asking.
TBH, I couldn't find any resource to back this answer, it works fine as far as my tests went, BUT I CAN'T SAY FOR SURE WHETHER THIS IS OR ISN'T RECOMMENDED TO USE. (Probably not)
Here is what I came up with:
$arr = array('kN1' => '50', 'kN2' => 400);
//$arr = array('50', 400);
foreach ($arr as $var => $var) { // use same variable for both key and value
print_r($var);
echo '<br>';
}
// kN1
// kN2
Run Viper
To get rid of the warning without introducing too much overhead just unset the unused variable once the loop is done.
foreach ($arr as $key => &$val) {
print_r($key);
}
unset($val);
BTW: I believe one should use a reference to the unused variable (&$val instead of $val). Otherwise you might end up producing a full copy of the variable with each iteration and that might be a costly operation.
Related
Can anybody provide an example of when php's list() function is actually useful or preferable over some other method? I honestly can't think of a single reason I'd ever actually want/need to use it..
Got a simple sql result row (numeric), containing, say, an ID and a name?
A simple solution to deal with it, can be:
list($id,$name)=$resultRow;
Edit;
or here's another: you want to know the current key/value pair of an array
list($key,$val)=each($arr);
this can even be put into a loop
while (list($key,$val)=each($arr))
altho you could say a foreach is exactly this; but if the
$arr changes in the meantime, well then it's not. It has its uses. :)
It's a handy function when you know the right hand side is returning an indexed array of a certain size.
list($basename, $ext) = explode('.', 'filename.png');
Note that it can be used in PHP 5.5 with foreach:
$data = [
['a1', 'b1'],
['a2', 'b2'],
];
foreach ($data as list($a, $b))
{
echo "$a $b\n";
}
But if you prefer more verbose code, then I doubt you'll think the above is "better" than the alternatives.
I would like to take an array and clear all of its values while maintaining its keys. By "clear" I mean replace with an empty type value, such as '' or null. PHP obviously has quite a few array functions, but I didn't find anything there that does exactly this. I am currently doing it this way:
foreach ($array as &$value) $value = ''
My question is, is there some built-in php function I overlooked, or any other way I can accomplish this without iterating over the array at this level?
Without knowing exactly what your memory/performance/object-management needs are, it's hard to say what's best. Here are some "I just want something short" alternatives:
$array = array_fill_keys(array_keys($a),""); // Simple, right?
$array = array_map(function(){return "";},$a); // More flexible but easier to typo
If you have an array that's being passed around by reference and really want to wipe it, direct iteration is probably your best bet.
foreach($a as $k => $v){
$a[$k] = "";
}
Iteration with references:
/* This variation is a little more dangerous, because $v will linger around
* and can cause bizarre bugs if you reuse the same variable name later on,
* so make sure you unset() it when you're done.
*/
foreach($a as $k => &$v){
$v = "";
}
unset($v);
If you have a performance need, I suggest you benchmark these yourself with appropriately-sized arrays and PHP versions.
Easiest way is array_map
$array = array_map(function($x) { return '';}, $array);
You can use array_keys to get the keys. You can then use array_flip if you like, although this will assign the values 0 through length-1 to the keys.
There is no single built-in function for this. You might try:
array_combine(array_keys($array),array_fill(0,count($array)-1,""));
But really the code you have right now does the job just fine.
If I need to change a function parameter, I can use foo(&$x) and the function can modify it.
I need something like this in a foreach loop,
$x=array(1,2,3);
foreach($x as &$i) $i=1;
var_dump($x);
results with some strange "&int(1)"...
array(3) {
[0]=>
int(1)
[1]=>
int(1)
[2]=>
&int(1)
}
But, of course, this is not the syntax (for what I whant)... It is possible to do this with PHP?
It is not "so elegant" to use for (now it works!),
$x=array(1,2,3);
for($i=0; $i<count($x); $i++) $x[$i]=1;
var_dump($x);
First off, this isn't technically a pointer. It is a reference. Before using them in your code, I'd suggest you get familiar with how they work in PHP by reading the manual section that explains them.
In this case, your code is actually correct, as documented in the manual page for foreach. foreach($x as &$i) is precisely the way to do this. Your confusion apparently comes from the output of var_dump:
&int(1)
This is precisely what you should expect. The & signifies that another variable is a reference pointing to this value. This is because $i continues to be a reference to the last element in the array even after the loop is over. This is potentially dangerous, because code elsewhere in your file may modify $i and therefore your array without you wanting it to.
It is probably good practice to unset $i after the loop is over to avoid this.
When a loop ends, the iterator still holds the last value used. In this case, the last item in the array. So it's still referenced. It doesn't really matter unless you try to reuse $i later, in which case you may get some weird results.
It would be safer to do something like this:
foreach($x as $k=>$v) {
$x[$k] = 1;
}
My homework affter good comments and answer at the comments.
Read the guide
As #lonesomeday says, "that is precisely the right syntax". The PHP guide shows that
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value)
$value = $value * 2;
unset($value); // break the reference with the last element
and, as #Wrikken say, needs the unset.
Use "intermediate elegance" when you are not sure
As #MarcB20 says, take care..."foreach($x as &$i) $i=1; is VERY dangerous. $i will REMAIN a reference for the duration of your code (or until you unset it), and you can unwittingly modify the contents of the array by reusing the variable in some other context down the road"...
So, you can use an "intermediate elegance" syntax,
foreach ($arr as $key=>$value) {
// ... use $value ...
$arr[$key] = $anothervalue;
}
prefer to use simple for (with array_keys if an array associative) if the $value not used.
I need to use PHP contants in foreach loop:
define('WEBS', 'http://google.com, http://yahoo.com');
foreach (WEBS as $a) {
//do something
}
However I managed to do that by following code, although it works fine but aptana editor shows syntax error. Please guide me how to do that in the correct manner.
foreach (get_defined_constants(true)['user']['WEBS'] as $w) {
//do something
}
You have to explode the values first
foreach (explode(', ', WEBS) as $url) { ...
explode() will break a string into an array so that you can iterate through it
Alternatively, you could even use preg_split.
foreach(preg_split('/,\s*/', WEBS) as $url) { ...
preg_split() allows you to split your string based on a regular expression. It returns an array. As an example, using this regex, the space following the comma is optional.
# a string like this
foo.com, hello.com,world.com, test.com
# would still split properly to
[
'foo.com',
'hello.com',
'world.com',
'test.com'
]
Regex methods are not always necessary. But I thought I'd show you that a little more control is available when it's necessary.
Aptana is showing you an error because you can't use [] after a func() prior to PHP 5.4. To get around that, you can do things like:
$constants = get_defined_constants(true);
$constants['user']['WEBS'];
But in this case WEBS should be just fine. The only issue you were having is that you needed to convert the string to an array first.
Looks like misuse of constants.
It seems you need a regular variable of array type.
$webs = array('http://google.com', 'http://yahoo.com');
foreach ($webs as $a) {
//do something
}
If you still thinks that constants is what you need - better ask another question, explaining why so, and be told of what you're doing wrong
Generally, we can extract an array, and also add an prefix to it, like this
extract($array, EXTR_PREFIX_ALL, "myprefix");
// which will give me output like $myprefix_myarrayvar
But, instead, is there a way to set a suffix instead of prefix? Something like,
$myarrayvar_mypostfix;
First of all, you should never use extract because it can make it very hard to tell where some variables are coming from, never mind possible collisions. You don't save much with extract .. it's really just a tool of laziness.
Anyway, since you asked, no there does not seem to be a way to add a suffix with extract natively, so you would have to do it on your own:
foreach ($array as $key => $val) {
${"{$key}_suffix"} = $val;
}
There is no extract option for that. So you need a workaround. You could either write a boring foreach or prepare the keys prior extraction:
extract( array_combine(preg_replace('/$/', "_suffix", array_keys($array)), $array) );