From my C++ knowledge base, I tend to initialize arrays in PHP by typing:
$foo = array()
Or I may bring this custom from Javascript, anyway, is this of any use?
As there's no problem in doing this:
$foo[45] = 'bar' without initializing it as an array, I guess not.
PS: the tags improvement is really good
Yes it is. At the very least in improves readability of code (so that you don't need to wonder 'where does $foo come from? Is it empty, or is there anything in it?`.
Also it will prevent 'Variable '$a' is not set notices, or Invalid argument passed to foreach in case you don't actually assign any values to array elements.
Either method is perfectly acceptable. As mentioned, this practice of using the array() construct is typically carried over from another language where you initialize before populating. With PHP, you can initialize an empty array and then populate later, or you can simply establish an array by assignments, such as $variableName[0] = "x";.
#petruz, that's the best way to do this, no only it will save you from nasty PHP error messages saying that function expects the parameter to be an array but, IMHO, this is the best way to write code. I initialise a variable before using it
Initializing variables before use is good practice. Even if it is not required.
I've had problems (in older versions of PHP, haven't tried recently) where I was acting on array with array_push or something and PHP barked at me. As a general rule it's not necessary, but it can be safer, especially if you're dealing with legacy code; perhaps you're expecting $foo to be an array, but it's actually a boolean? Bad things ensue.
It's good practice. Sooner or later you'll encounter a situation where you might want to do something like this:
array_push($foo, '45');
Which will throw a notice, whereas:
$foo = array();
array_push($foo, '45');
won't.
With initialization:
$myArray = array();
if ($myBoolean) {
$myArray['foo'] = 'bar';
}
return $myArray;
Without initialization:
if ($myBoolean) {
$myArray['foo'] = 'bar';
}
return $myArray;
In the first case it's clear what you want to happen if $myBoolean is false. In the second case it is not and php may throw a warning when you try and use $myArray later. Obviously this is a simplified case, but in a complex case the "if" may be a few lines down and/or not even exist until someone comes along and adds it later without realizing the array wasn't initialized.
While not necessary, I have seen lack of initialization cause non-obvious logic problems like this in complex functions that have been modified a lot over time.
Related
What's the best way to treat a situation like this:
I personally always have used this way, creating a variable with type array and assigning the function to it. But when I started to using NetBeans 8, it shows me a warning, saying that must be only 1 attribution to a variable.
I think this way is more verbose and makes the code more readable.
Should I just create this way?
$test = returnArray();
check out this article, they discuss this in the portion titled immutable variables. It seems like the second way is the recommended method.
Just keep things simple. No need for declarations.
function returnArray() {
return array('test' => 'test');
}
$array = returnArray();
I'm writing some code that builds up associative array of counters. When it encounters a new item for the first time it creates a new key and initializes it to zero. I.e.:
if (!array_key_exists($item, $counters)) {
$counters[$item] = 0;
}
$counters[$item]++;
However, PHP actually does that first part implicitly. If I just do...
$counters[$item]++;
... then $counters[$item] will evaluate to NULL and be converted to 0 before it's incremented. Obviously the second way is simpler and more concise, but it feels a little sleazy because it's not obvious that $counters[$item] might not exist yet. Is one way or the other preferred in PHP?
For comparison, in Python the idiomatic approach would be to use collections.Counter when you want keys that initialize themselves to 0, and a regular dictionary when you want to initialize them yourself. In PHP you only have the first option.
Incrementing an uninitialized key will generate a PHP Notice, and is a bad idea. You should always initialize first.
However, the use of array_key_exists is not very idiomatic. I know coming from Python it may seem natural, but if you know that $counter has no meaningful NULL values it's more idiomatic to use isset() to test for array membership. (It's also much faster for no reason I can discern!)
This is how I would write a counter in PHP:
$counters = array();
foreach ($thingtobecounted as $item) {
if (isset($counters[$item])) {
$counters[$item]++;
} else {
$counters[$item] = 1;
}
}
Unfortunately unlike Python PHP does not provide any way to do this without performing two key lookups.
the first is preferred. the second option will generate a Notice in your logs that $counters[$item] is undefined. it still works but if you change display_errors = On; and error_reporting = E_ALL. in your php.ini file you will see these notices in your browser.
The first way is generally how you do it, if for nothing other than simpler maintenance. Remember, you may not be the one maintaining the code. You don't want error logs riddled with correctly operating code. Even worse, you may need to transfer methods to other languages (or earlier versions of PHP) where implicit initialization might not occur.
If you don't really need a check on each array index - or know that most of the indexes will be undefinded - why not suppress errors like: ?
(this way you save some performance on initializing [useless] indexes)
if (#!array_key_exists($item, $counters)) {
I was wondering if it is always necessary to use something like is_array() before every foreach i do.
In case the variable is not an array, it throws an error.
So i always use:
if(is_array($users)) {
foreach($users as $user){
}
}
What would you recommend me?
Thanks.
Well if you know your code well enough, there should be no reason to have to check if it is an array.
Otherwise, if the variable changes type that often I would suggest tweaking your code a bit so it does not do that.
Other than that, using that if statement is the way to go.
If you're sure that something is an array or otherwise implements Iterable, you obviously don't need the extra if condition. If you're not sure, then obviously checking the type will make your code more reliable.
Some hacks I've seen include casting the variable to an array: (array)$users. This is not recommended though, it's better to explicitly check the type.
Also, if this is code inside a function you can use argument typing:
function mycode(array $users)
{
foreach ($users as $user) { }
}
When the function is called with the wrong type it will trigger an error.
Assuming this happens in a function:
function doSomethingWithUsers($users)
{
if(!is_array($users))
{
throw new Exception('$users is expected to be an array');
}
foreach($users as $user){
...
}
}
This way you'll immediately see whenever it's called with the wrong parameters.
In general, it's better not to.
A good general principle in programming is not to hide or ignore errors.
If a variable should be an array, it does you no service to specifically ignore the situation if it's not an array. Instead, it is better for you to be informed of the problem with the built-in error handling. Otherwise, you're not fixing the problem, just hiding its effects. This can make debugging subsequent problems difficult.
However, there's a number of assumptions here:
This is assuming that the variable is supposed to be an array. If you're using foreach () on it, I assume this to be the case. If you're running foreach () on something that might legitimately not be an array it might be an indication your code may need re-working.
Your error reporting and/or logging (reporting on a development server, logging on production) needs to be set up correctly in order to benefit from what PHP errors tell you. Specifically, it's almost never a good idea to ignore PHP warnings - despite being called "warnings" they usually indicate a failure which (in my opinion) should stop execution.
That said, it's not necessarily wrong to use an is_array() in front of a foreach ().
What would you recommend me?
Yes it is good idea and such considerations make you a defensive programmer :)
It's better for me:
foreach (is_array($arr) ? $arr : array() as $key=>$val) {
//..
}
I ran into this php syntax the other day and I am not familiar with it. I *guessed it might doing a push, but I really don't know. Is this *exactly the same as array_push($b). If it is accomplishing something *similar, please explain how it is different.
$foo = array();
foreach($bar as $b)
{
$foo[] = $b; //push?
}
The only difference is the tiny bit of extra overhead involved in making a function call to array_push() vs making use of the language construct [] to append onto an array. They are functionally equivalent.
The difference between them from that function call is going to be utterly miniscule to the degree that you needn't worry about it unless you are doing it millions of times.
$foo[] = $b will be slightly faster due to the overhead of a function call (as Michael stated below).
Additionally, as stated in the manual, if the first argument to array_push is not an array a notice is raised. Using the array bracket notation will simply create a new array if it does not already exist.
With PHP5 using "copy on write" and passing by reference causing more of a performance penalty than a gain, why should I use pass-by-reference? Other than call-back functions that would return more than one value or classes who's attributes you want to be alterable without calling a set function later(bad practice, I know), is there a use for it that I am missing?
You use pass-by-reference when you want to modify the result and that's all there is to it.
Remember as well that in PHP objects are always pass-by-reference.
Personally I find PHP's system of copying values implicitly (I guess to defend against accidental modification) cumbersome and unintuitive but then again I started in strongly typed languages, which probably explains that. But I find it interesting that objects differ from PHP's normal operation and I take it as evidence that PHP"s implicit copying mechanism really isn't a good system.
A recursive function that fills an array? Remember writing something like that, once.
There's no point in having hundreds of copies of a partially filled array and copying, splicing and joining parts at every turn.
Even when passing objects there is a difference.
Try this example:
class Penguin { }
$a = new Penguin();
function one($a)
{
$a = null;
}
function two(&$a)
{
$a = null;
}
var_dump($a);
one($a);
var_dump($a);
two($a);
var_dump($a);
The result will be:
object(Penguin)#1 (0) {}
object(Penguin)#1 (0) {}
NULL
When you pass a variable containing a reference to an object by reference, you are able to modify the reference to the object.