Blog do Regis – Meus aprendizados

O que ando aprendendo nesta caminhada sobre a Terra


Today, I was writing a script in PHP to be used in the command line when I came across unexpected behavior (at least on my part).
The script should receive three arguments, the last of them a list containing one or more numeric codes.
Trying to validate this last argument was getting a different result than imagined.
See the code snippet that I was using:

// test.php
if (php_sapi_name() == 'cli') {
    $di = isset($argv[1]) ? $argv[1] : date('Y-m-d'); // Initial Date
    $df = isset($argv[2]) ? $argv[2] : date('Y-m-d'); // Final Date
    $prods = isset($argv[3]) ? explode(',', $argv[3]) : array(); // Code List

    ##### Validating
    // Initial Date
    if ($di != date('Y-m-d', strtotime($di))) {
        echo "\n";
        echo "ERROR! Invalid INITIAL DATE!\n";
        exit;
    }
    // Final Date
    if ($df != date('Y-m-d', strtotime($df))) {
        echo "\n";
        echo "ERRO! Invalid FINAL DATE!\n";
        exit;    
    }

    // Codes
    if (count($prods) > 0) {
        foreach ($prods as $prod) {
            if ($prod != (int)$prod) {
                echo "\n";
                echo "ERROR! The CODE " . $prod . " is invalid!\n" ;
                exit;
            }
        }
    }
    echo "DONE!";
}

Interestingly, when I ran

# php -f test.php 2015-12-10 2015-12-11 33b

the result was

# DONE

and reversing the condition to

        if ($prod == (int)$prod)

show the expected message.
I tried to assign to a separate variable and still continued not working.

            $check = (int) $prod;
            if ($prod != $check) {

Whyyy??

The Type Comparison

!==

  cannot be used here, since all arguments will be strings. When I though about this I got the answer.

So I did some command line tests and I check for the actually behavior of PHP Comparisons.

When we do things like: 

$string == $integer

 PHP will always do a CAST from String to the other type before comparison, so the code

$string == (int) $string

  will always return true, since $string will be changed to int in both sides.

To avoid this kind of trouble, is necessary to have the same type in both sides of comparison.

            $conf = (int) $prod;
            if ($prod != (string) $conf) {
            // OR
            if ($prod != (string)(int)$prod) {

See you.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.

Blog do Regis - Meus aprendizados
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.