Comparison operator or isset()?

Asked

Viewed 447 times

1

I’m developing an application for lotteries, where every generated game goes through N filters before the numbers are shown. Dozens are chosen, passed through via $_POST for a php file that will do the rest.

In it I had a code basically like this:

foreach ($jogos_gerados as $jogos) {
    if ($_POST['filtro_1'] == 'on') {
        // Procedimentos do filtro
    }
    if ($_POST['filtro_2'] == 'on') {
        // Procedimentos do filtro
    }
    // E assim se repetia por mais 120 filtros
}

Well, it turns out that for the treatment of approximately 150,000 bets I was having a very large processing time even when I was not activating the filters $_POST['filtro_X'] == 'off'. Then I decided to trade everything in this way:

foreach ($jogos_gerados as $jogos) {
    if (isset($_POST['filtro_1'])) {
        // Procedimentos do filtro
    }
    if (isset($_POST['filtro_2'])) {
        // Procedimentos do filtro
    }
    // E assim se repete por mais 120 filtros
}

And the time has dropped drastically to < 5s. What I’m curious to know is why this big difference between isset() and a comparison operator. Since in my view, both have to be checked if it exists to enter the filter (TRUE for isset() and ON for the comparison operator).

  • 2

    You have not been at all curious whether there is any way you avoid having to do more than 100 ifs?

  • @Andersoncarloswoss I know I could do in other ways, but I’m just curious to understand what happened.

3 answers

5


The function¹ isset() and the comparison of values are different things, they do different things and their use is not exclusive to each other. The isset() checks if a variable is defined in the current scope, returning true when it is, regardless of the value; the operator == compares the value of the variable and not whether it is defined. In fact, the operator == even generates an error when the variable is not defined.

That is, you use isset() when you want to check whether a variable is defined and the operator == to check the value. In general, the two are used concurrently, because before checking the value you should check if it is set.

Just to highlight my comment, if you need to do more than 100 checks on your program, it’s a good sign that you will need to refactor it. Apparently you are sending the values of filters as on or off and that doesn’t make much sense. You could send by request only the filters that are active and so go through the list normally at $_POST with the foreach. If this request is coming from HTML, these fields should possibly be checkbox, nay radio or any other.

I will not comment on the difference in execution times between the two because it makes no sense to compare different things.

[1] The isset() is actually a language builder, not a function, and for PHP there are considerations to be made.

  • Got it, thanks Anderson!

3

The isset is only to check if a variable or key exists within an array or stdObject, it is important to note that if the variable has the value NULL will also return false, so as examples:

<?php
$foo = 1;
$bar = 2;
$baz = null;

var_dump(isset($foo)); //Retorna true
var_dump(isset($bar)); //Retorna true
var_dump(isset($baz)); // Retorna false
var_dump(isset($naodeclarada)); // Retorna false

Example of use with an array:

<?php
$foo = array(
    'bar' => array(
        'baz' => 1
    )
);

var_dump(isset($foo['bar']['baz'])); //Retorna true
var_dump(isset($foo['bar']['baz']['teste'])); //Retorna false

Would be similar with stdClass:

<?php
$foo = new stdClass;
$foo->baz = new stdClass;
$foo->baz->bar = 1;

var_dump(isset($foo->baz->bar)); //Retorna true
var_dump(isset($foo->baz->bar->teste)); //Retorna false

It is also important to note that isset can be used to check multiple values at the same time:

if (isset($_POST['foo'], $_POST['baz'], $_POST['bar'])) {
    //Executa
}

It would be the same as:

if (isset($_POST['foo']) && isset($_POST['baz']) && isset($_POST['bar'])) {
    //Executa
}

Note that variables in PHP with type value string may work similar to arrays, for example:

$foo = 'abc';

var_dump($foo{1}); //Irá exibir "a"
var_dump($foo{2}); //Irá exibir "b"
var_dump($foo{3}); //Irá exibir "c"

That is to check if a variable has content, we usually use !empty, that would look like this:

if (!empty($_POST['foo']) && !empty($_POST['baz']) && !empty($_POST['bar'])) {
    //Executa
}

How different from isset will check if the variable is empty, however you can do so:

if (isset($_POST['foo']{1}, $_POST['baz']{1}, $_POST['bar']{1})) {
    //Executa
}

Which would make it a lot easier, but of course it’s important to note that empty does much more than checking empty strings, for it to consider a variable as empty it may contain the following types of values:

  • "" (an empty string)
  • 0 (when it is an integer equal to zero)
  • "0" (zero as string)
  • NULL
  • FALSE
  • array() (an empty array)
  • public $var; (When a variable is declared in a class but has no value as it is NULL)

As I explained in /a/117504/3635, namely the empty may have more uses than the isset will be able, use both as needed.

Now about comparing with == it is important to note that if you do not have isset or empty to check first probably whether the error_reporting in the php.ini is configured with E_NOTICE or E_ALL it will send messages (that are not mistakes) if you are in a folder with GET (or any type that is not POST) try to do this:

<?php
if ($_POST['foo']) {

}

Or:

$foo = $_POST['foo'];

The following message will be displayed:

Notice: Undefined index: foo in pagina.php

The message means that the super-global POST exists, but the index (refers to key) call foo there is no.

So for your specific code maybe the ideal would be something like this:

foreach ($jogos_gerados as $jogos) {
    //Checa se tem no minimo 2 caracteres e se é "on"
    if (isset($_POST['filtro_1']{2}) && $_POST['filtro_1'] == 'on') {
        // Procedimentos do filtro
    }

    //Checa se tem no minimo 2 caracteres e se é "on"
    if (isset($_POST['filtro_2']{2}) && $_POST['filtro_2'] == 'on') {
        // Procedimentos do filtro
    }
}

However being inside a loop, which is the foreach, I think that multiple checks are unnecessary, you could optimize the performance and even the writing, could do something like:

function getFilters()
{
     $filters = array();

     //O 200 aqui é a quantidade possivel de filtros que você terá, pode editar
     for ($i = 1; $i <= 200; $i++) {
         $key = 'filtro_' . $i;

         //Faz uma comparação "inline" e salva no array
         $filters[$i] = isset($_POST[$key]{2}) && $_POST[$key] == 'on';
     }

     return $filters; //Retorna o array
}

//Pega os filtros
$filtros = getFilters(); //Irá retornar algo como array( 1 => true, 2 => false, ...)

foreach ($jogos_gerados as $jogos) {
    //Não precisará de isset, pois existe, só que é false ou true dependo do valor de filtro_1
    if ($filtro[1]) {
        // Procedimentos do filtro
    }

    //Não precisará de isset, pois existe, só que é false ou true dependo do valor de filtro_2
    if ($filtro[2]) {
        // Procedimentos do filtro
    }
}
  • because you used === 'on' in getFilters() instead of == 'on'? The result would not be the same?

  • @Thiago force of habit, is that === compares the type and I always end up making use of it, institivamente, but for your case is not very necessary, although it is reasonably more performatico (but only if you have some 1000 loops to notice something different)

  • @Hiago an example about the use of ===, ==, !== and !===: How to distinguish FALSE from empty string?

  • 1

    I get it, it sounds silly but it’s important details. Thanks for the explanations @Andersoncarloswoss and Guilherme!

  • @Thiago yes, it is important to understand how the strings behave, you will have many benefits. A question, came to test the function getFilters that I created? Any problems let me know.

Show 1 more comment

1

The isset() returns a boolean value, true or false, that is, checks whether or not the variable exists.

Check if the variable has a value set with == is more difficult for the server, because, in addition to receiving the POST, you should check if its value is as expected. No isset(), the server runs only 1 step, true or false.

The sensitive performance improvement in your application is because PHP does not need to check whether the value is "on", "off" or anything.

  • I understand, anyway I will try to optimize my application. Thanks @dvd!

  • @Thiago Thanks!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.