I've noticed on XAMPP that strict error reporting is on and I get undefined index errors now. I just have two small questions (I'm still learning here):
I know you don't have to declare variables in PHP but is there any advantage to declaring them anyway? If not, why do I get errors when strict error reporting is on when I don't define them?
When I use get variables for example, I check for their value before I run a function like
if($_GET['todo'] == 'adduser')
runFunctionAddUser();
This gives an error because I never check if the get variable exists first. Should I do
if(isset($_GET['todo']))
if($_GET['todo'] == 'adduser')
runFunctionAddUser();
instead? Would there be an advantage to this or would it be unnecessary and slow?
This thread is abit old but I did some tests relating to the question so I might as well post it:
The testing code (PHP 5.3.3 - CentOS release 6.5 (Final)):
class NonExistant
{
protected $associativeArray = array(
'one' => 'one',
'two' => 'two',
'three' => 'three',
'four' => 'four',
'five' => 'five',
'six' => 'six',
);
protected $numIterations = 10000;
public function noCheckingTest()
{
for ($i = 0; $i < $this->numIterations; $i++) {
$this->associativeArray['none'];
}
}
public function emptyTest()
{
for ($i = 0; $i < $this->numIterations; $i++) {
empty($this->associativeArray['none']);
}
}
public function isnullTest()
{
for ($i = 0; $i < $this->numIterations; $i++) {
is_null($this->associativeArray['none']);
}
}
public function issetTest()
{
for ($i = 0; $i < $this->numIterations; $i++) {
isset($this->associativeArray['none']);
}
}
public function arrayKeyExistsTest()
{
for ($i = 0; $i < $this->numIterations; $i++) {
array_key_exists('none', $this->associativeArray);
}
}
}
The results are:
| Method Name | Run time | Difference
=========================================================================================
| NonExistant::noCheckingTest() | 0.86004090309143 | +18491.315775911%
| NonExistant::emptyTest() | 0.0046701431274414 | +0.95346080503016%
| NonExistant::isnullTest() | 0.88424181938171 | +19014.461681183%
| NonExistant::issetTest() | 0.0046260356903076 | Fastest
| NonExistant::arrayKeyExistsTest() | 1.9001779556274 | +209.73055713%
All the functions are called the same way with via call_user_func()
and timed with microtime(true)
Observations
empty()
and isset()
are the clear winners over the other 2 methods here, the two methods are pretty much tied on performance.
is_null()
performs bad because it needs to lookup the value first, pretty much the same as just accessing the non-existant value $this->associativeArray['none']
, which involves a full lookup of the array.
However, i'm surprised by the performance of array_key_exists()
. Where it is 2 times slower than empty()
and isset()
.
NOTE:
All the functions I've tested have different uses, this benchmark is only here for the most generic use case where you want to quickly check the value in an array. We can go into argument of whether null
should be considered a "value" or simply an indicator of non-existence, but that's another topic. o.o
UPDATE 2017-01-20
Use PHP 7.1
Fixed bug mentioned by @bstoney
$ php -v
PHP 7.1.0 (cli) (built: Dec 2 2016 03:30:24) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
$ php -a
php > $a = ['one' => 1, 'two' => 2, 'three' => 3];
php > $numIterations = 1000000;
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { $a['none']; }; echo microtime(true) - $start;
0.43768811225891
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { empty($a['none']); }; echo microtime(true) - $start;
0.033049821853638
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { is_null($a['none']); }; echo microtime(true) - $start;
0.43995404243469
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { isset($a['none']); }; echo microtime(true) - $start;
0.027907848358154
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { array_key_exists('none', $a); }; echo microtime(true) - $start;
0.049405097961426