Is there a difference in using constants or variables in Classes?

Asked

Viewed 564 times

5

There is a difference in using constants or variables in Classes?

2 answers

5

Yes, there are differences. Constants cannot be changed, regardless of whether they are in classes or not, it is as if they are readonly (read-only), in addition they are always static, i.e., the value is not changed for each object:

class Foo {
   const a = 1;
   public $b = 1;

   public function __construct() {
        self::a = 2; //Irá causar erro
   }
}

Another example

class Foo {
   const a = 1;
   public $b = 1;

   public function __construct() {
        $this->b = 2; //Não irá causar erro
   }
}

Constants have these characteristics:

  • Requires PHP 5.3.0
  • Are always public
  • Cannot be changed, the value will always be that of the moment it was declared
  • Access is static (since there is no need to change as an object)

A hint, it is possible to use the function constant (which in most cases can be somewhat redundant) both of a interface, classe or define:

<?php
define("MAXSIZE", 100);
echo MAXSIZE;
echo constant("MAXSIZE"); // mesma coisa que a linha anterior


interface bar {
    const test = 'foobar!';
}

class foo {
    const test = 'foobar!';
}

$const = 'test';

var_dump(constant('bar::'. $const)); // string(7) "foobar!"
var_dump(constant('foo::'. $const)); // string(7) "foobar!"

Using with spl_autoload (PSR-0 and PSR-4)

There is a small advantage between using const compared to the define PHP, when we use installations via Composer or any system that is based on PSR-0 or PSR-4, if the class we create uses define and only need the value of the constant so:

<?php
namespace Foo;

define('FOO_BAR', 2);

class Baz
{
}

And we try to load like this, it won’t trigger the autoload:

<?php
require 'vendor/autoload.php';

var_dump(FOO_BAR);

So it even triggers the autoload, but does not find the class because in PSR we use:

<?php
require 'vendor/autoload.php';

var_dump(Foo::FOO_BAR);

Yet if we do so:

<?php
namespace Foo;

class Baz
{
    const BAR = 2;
}

And try to load it like this:

<?php
use Foo\Baz;

require 'vendor/autoload.php';

var_dump(Baz::BAR);

4

His name says it all.

Constants cannot be changed. Variables, as the name says, can be changed.

So, briefly, use constants when you need an immutable value or important information. And the variables you should use in cases where the information may vary.

A small correction is that when it comes to classes the correct nomenclature is estates, and not variables.

In PHP, when it comes to constants we have some small differences, such as the fact that, for example, a constant can be declared in an interface, different from the properties that cannot be declared there.

Example:

interface Searchable {
     const FLAG = 1;
}

class Search implements Searchable {}

echo Searchable::FLAG;
echo Search::FLAG;

Recommendations

One of the recommended uses for constants is PHP enumeration simulation.

For example, suppose my class has a method that accepts the actions "fly", "land" and "shut down". It is not elegant to let the user have to pass the string with these options, so in this case, I believe that the counts have a good utility.

Behold:

 class Aviao {

      const ACAO_POUSAR = 'pousar';

      const ACAO_VOAR = 'voar';

      const ACAO_DESLIGAR = 'desligar';


       public function acao($acao) {
           if ($acao === self::ACAO_VOAR) {

           } elseif ($acao === self::ACAO_POUSAR) {

           } elseif  ($acao === self::ACAO_DESLIGAR) {

           } else {
              throw new Exception("Ação inválida");
           }
       }

 }




$airbuss = new Aviao();
$airbuss->acao(Aviao::ACAO_VOAR);

Another important way of using constants is when we need to use "flags" to define some behavior.

Suppose you have a log class, where 1 means "normal" and 2 means "priority". It would be easier to use constants to define these "flags"

class Log {


       const NORMAL = 1;

       const PRIORIDADE = 2;

       public function write($value, $severity = self::NORMAL) {
            if ($severity == self::NORMAL) {
                 echo $value;
            } elseif ($severity = self::PRIORIDADE) {
                echo "Urgente: $value";
            } else {
               throw Exception("opção inválida");
            }
       }
}

Still using another way to show the importance of constants, see an example of the passage of default values to a time formatting. If one day the formatting changed, just change the constant, and everything else would be changed.

Example:

 $time = Time::create(20, 10, 0);

 $time->format(Time::DEFAULT_FORMAT);

NOTE: From PHP 5.6 it is possible to define array in constants.

  • The code is just for example, or is it good to use Exception in this case?

  • 1

    It is an example. I could do so if it were something "more serious" in relation to the argument, for example, if the guy passes an integer, rather than passing an object

Browser other questions tagged

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