PHP array vs [ ] in method and variable declaration
PSR-2 and PSR-12 (by PHP Framework Interoperability Group) do not mention short array syntax. But as you can see in chapter 4.3 they use short array syntax to set the default value of $arg3
to be an empty array.
So for PHP >= 5.4 the short array syntax seems to be the de-facto standard. Only use array()
, if you want your script to run on PHP <5.4.
The speed of variables vs arrays in php
Speed and memory are likely to be irrelevant. Write clean, direct code.
If you are going to be iterating or searching these values, use an array.
As a fundamental rule, I don't declare single-use variables. Only in fringe cases where readability is dramatically improved do I break this rule.
Should Class Properties be Stored as Variables or in an Array
It all depends on what you are trying to acchieve. Storing all properties in an (associative) array will make life easier for you if you wish to implement any of the Traversable
interfaces, though there are ways to do this, too, with predefined properties.
If by best, you mean fastest: defining each property beforehand will make your classes more performant as I explained here already
There are, of course, a lot more reasons why the first approach is the better one I've listed them here
Basically, what you need to know is that PHP's "overloading" of objects is slow (O(1) for declared properties vs O(n) for overloaded properties). The same goes for magic methods, like __get
and __set
. They're slow. Consider this:
class Declared
{
private $foo = 123;
public function setFoo($val)
{
$this->foo = (int) $val;
return $this;
}
public function getFoo()
{
return $this->foo;
}
public function __get($name)
{
$name = 'get'.ucfirst($name);
if (method_exists($this, $name))
{
return $this->{$name}():
}
//return null or throw exception
throw new RuntimeExcpetion('attempted to access non-existing property using '.$name.' in '.__METHOD__);
}
public function __set($name, $val)
{
$mname = 'set'.ucfirst($name);
if (method_exists($this, $mname))
{
return $this->{$mname}($val):
}
throw new RuntimeException($name.' is an invalid property name');
}
}
Not only can I be certain that, at no point, new properties will be added, but because I'm using custom getters and setters, I can also ensure that the type of each property is what I want/expect it to be. In this example, I need $foo
to be an integer, so in the setter, I cast whatever value that is being passed as an argument to an int. You can do that in a magic __set
method, too, but the more properties you're dealing with the messier that method will become (tons of if's and else's).
Compare this, now, to this class:
class NotDeclared
{
private $data = array('foo' => 123);
public function __get($name)
{
return isset($this->data[$name]) ? $this->data[$name] : null;
}
public function __set($name, $value)
{
$this->[$data] = $value;
}
}
Now, this class does look a lot shorter, so I can see why this would appeal to anyone. Yet, let's compare both in terms of usage:
$declared = new Declared;
$notDeclared = new NotDeclared;
echo $declared->foo;//ok
echo $declared->getFoo();//ok
echo $notDeclared->foo;//ok
$declared->foo = 34;//fine
$declared->setFoo($declared->foo*2);//just fine
echo $declared->fo;//TYPO => exception
echo $notDeclared->fo;//no errors show, but echoes nothing: invisible bug?
//Worse, still: 2 mistakes in one go
$notDeclared->fo = 'Typo, meant foo, but assign string to expected integer property';
$declared->fo = 'asd';//throws excpetion at once
//singe $notDeclared->fo didn't throw excpetions, I'm assuming I reassigned $foo, yet
echo $notDeclared->foo;//ecoes old value
Because I'm restricting the usage of __set
, by throwing excpetions when the user attempts to assign non-existing properties, any typo will throw an excpetion immediatly. If you don't do so, you might end up having to back-track an instance of your object, in order to spot a single, silly typo, like the example I have shown here with fo
What's more: You have to think about when the magic methods are called:
$instance->newProperty;
What is going on behind the scenes?
- check object instance for a public property called
newProperty
- check object for method called
newProperty
(syntax error) - check object for
__get
method - invoke
__get
method- lookup data property (
$this->data
) - check array for
newProperty
key (isset
) - return result of ternary (ie null)
- lookup data property (
This means that $instance->newProperty
requires PHP to lookup newPropery
, then the __get
method, then the $data
property, then lookup the newPropery
key in that array, and then return null, or the value. that's a lot of searching on one object.
That's why I'll always recommend the first option.
compact() vs manual array declaration on PHP
I think it's more a matter of preference.
Uses
If I have a bunch of local variables declared, and I happen to want my array keys to be named the same way, compact
is very helpful.
I don't find that to be the case very often though. Typically I'm defining an array that is more complex:
$array = [
'foo' => $something->foo(),
'bar' => $bar,
'baz' => A_CONSTANT
];
To use compact
here you'd have to define your variables $foo
$bar
and $baz
first, which seems silly.
I like compact
, I just don't find it to be all around helpful most of the time.
Performance
Ok I had to go do it. Here's a very basic non-scientific performance comparison:
https://3v4l.org/WTrOJ
In short, using compact
is an order of magnitude slower.
And yet, you have to use it 100,000 (in this example) to matter a tiny fraction of a second.
In other words: use what makes the most sense for your code. Don't worry about the incredibly small performance difference!
In PHP, what is the difference between declaring a variable as global inside function, or passing the variable as an argument to the function?
There are a lot of questions here, I will try to walk through them...
What is the difference between declaring a variable within a function as global or public/private VS passing it to a function as an argument?
global
is a type of variable scope. Declaring a variable as global
is generally considered bad practice and you should try to avoid it. By passing the variable to a function as an argument, the code is more reusable because you know what the function expects and it isn't relying on some unknown mystery global variable.
public
, private
, protected
are types of visibility used in object oriented programming. These basically determine how properties and methods within a class can be accessed by other classes.
it took me hours to figure out that I needed to pass it into the function as an argument by reference
Something to understand about functions is that unless you pass arguments by reference you are working with a copy of the variable, not the original.
why doesn't it work to pass the variable in as
global
then edit it and spit it back out withreturn
or simply by doing something like concatenating to the variable array?
You wouldn't need to return
a global
variable, because you're working with the original value. Please refer again to the link above about scope.
Another example I recently ran into is by making a function for PHPMailer, where I am passing it several arguments, like email-to address and message body, but I also need to pass it authentication strings, like API key, etc.
There are several ways to approach this in addition to using global
. If you are planning to use this authentication key in more than one place, the easiest solution would probably be to define a constant, for example:
define('AUTH', 'my_key');
function phpMailer( $mail_to = "to@email.com", $mail_from = "a@b.com" ) {
echo AUTH;
}
But again, the function is now less reusable because it is dependent on that constant. A better solution would probably be to wrap it in an object:
class phpMailer()
{
private $auth = 'my_key';
public function send($mail_to, $mail_from)
{
$this->auth;
}
}
$mail = new phpMailer();
$mail->send('to@email.com', 'a@b.com');
Hopefully this helps. The online PHP documentation found in the links above contain a wealth of information.
Is it necessary to declare PHP array before adding values with []?
If you don't declare a new array, and the data that creates / updates the array fails for any reason, then any future code that tries to use the array will E_FATAL
because the array doesn't exist.
For example, foreach()
will throw an error if the array was not declared and no values were added to it. However, no errors will occur if the array is simply empty, as would be the case had you declared it.
Related Topics
Best Way to Autoload Classes in PHP
Should Lock_Ex on Both Read & Write Be Atomic
Alternative to Money_Format() Function
How to Loop Through a Multidimensional Array Without Knowing It's Depth
Can Closing the Browser Terminate the PHP Script on the Server
MySQL or PHP Is Appending a  Whenever the £ Is Used
Aggregated Query Without Group By
PHP Exec: Does Not Return Output
Curl Requires Curlopt_Ssl_Verifypeer=False
When Do I Use PHP_Eol Instead of \N and Vice-Versa? Ajax/Jquery Client Problem
How to Use File_Get_Contents() to Compare Two Files
How to Take an Array, Divide It by Two and Create Two Lists
Add a Quantity Field to Ajax Add to Cart Button on Woocommerce Shop Page
How to Set for Specific Directory Open_Basedir