Practical use of Constant scalar Expressions in PHP and other languages

Asked

Viewed 302 times

6

In the PHP 5.6 we will have an appeal appointed Constant scalar expressions. The manual provides some examples, but the main focus would be:

  • How to use the functionality correctly, without doing so anti-pattern?
  • Do other languages implement this type of resource? How it works and is used in them?
  • The variables.less Bootstrap would be an example of this concept?
  • 2

    Complicated answer why own Feature is already almost a antipattern. Constants are... hell, constant, immutable. From the moment you, programmer, use variables, make calculations, change programmatically, is no longer constant. So much for implementing and people shoot themselves in the foot like that...

  • @Brunoaugusto You can imagine the worst-case scenario using the new functionality?

  • 1

    In my opinion there is no worst-case scenario because they are all bad. The example you presented may even make some sense, but every didactic example, in a sense, makes sense. But in the real world, in real Applications I see this gambiarra.

  • @Brunoaugusto Constant scalar Expressions looks a lot like what is used in variables.less bootstrap. The purpose of my question is to understand how Constant scalar Expressions is used in other languages to define when we will use this tool correctly. So far I agree with you and hope to work a little more on this theme

  • It would be good, then, to highlight this particular question (about other languages) because it got a little lost in the middle of the topic.

  • @Brunoaugusto, what is your opinion on the amendment of the question?

  • See if the new wording was good. I dried up enough to focus more on the concept and technique than on the implementation and use. Anything, just edit again and complement something pertinent that might have been cut in excess (I don’t think).

  • @Brunoaugusto Let’s see how the answers look from the question as it is. Thank you!

  • I agree with @Brunoaugusto, I do not think this Feature is something so interesting in terms of applicability and a new utility, but yes, one more way to do something that was already possible in php, I followed this question trying to be convinced otherwise, but so far no.

  • 1

    Thanks for the @Marceloaymone review. So far, I see the use of functionality where more than one occurrence of the same default value is used in more than 2 method parameters in the same object.

  • What happened to the examples of the question?

  • @gmsantos, Brunoaugusto proposed a new formatting of the question, simplifying it. What you found ?

  • @Brunoaugusto, what is your assessment of the response given by neoprofit?

  • @Marceloaymone , what is his assessment of the response given by neoprofit?

  • Honestly, it was not a bad answer, but it lacked at least one practical (and best written) example for both scenarios, good and bad. Mainly for the misuse, since that App::() was a little out of context for me.

Show 10 more comments

3 answers

3


This functionality is not widespread among other languages and there is also no good practice found by common sense, so my opinion is that this new functionality will be very well used by some and by others will be used as a new form of "gambiarra".

Personal opinion:

Good use:

  • Calculate default values for method arguments;

In this example, if you want to change the default limit, from 5 to 10, it will change in one place:

<?php
class Foo {
    const DEFAULT_LIMIT = 5;

    public function bar($limit = self::DEFAULT_LIMIT) {
        //code
    }

    public function wonka($limit = self::DEFAULT_LIMIT) {
        //code
    }
}

Misuse:

  • Calculation of urls and paths in constants, since this can be used as always, using define() or still creating objects and methods specialized in delivering Paths information for example.
  • please improve your examples of good and bad use?

2

An interesting example are configuration variables.

For example, suppose a scenario where services are consumed, or a basis of approval, or production. These services originate through a URL, which varies depending on the basis in question.

Therefore, listed Urls for these services can be determined by a flag that determines whether the application is in production mode or type approval. See the following example:

// variavel que define ambiente - homogação ou produção
$isHomolog = true;

// constantes para ambiente de homologação
const URL_SERVICO_1_HOMOLOG = "http://homolog1.com";
const URL_SERVICO_2_HOMOLOG = "http://homolog2.com";

// constantes para ambiente de produção
const URL_SERVICO_1_PRODUCTION = "http://production1.com";
const URL_SERVICO_2_PRODUCTION = "http://production2.com";

// constantes utilizadas para os serviços
const URL_SERVICO_1 = $isHomolog ? URL_SERVICO_1_HOMOLOG : URL_SERVICO_1_PRODUCTION;
const URL_SERVICO_2 = $isHomolog ? URL_SERVICO_2_HOMOLOG : URL_SERVICO_2_PRODUCTION;

In this example, constants are defined for the type-approval and production environment. In addition, the variable $isHomolog identifies whether the environment is type-approval (value true) or output (value false). Hence, the service variables used by the system URL_SERVICO_1 and URL_SERVICO_2 has its value conditioned to environment variable $isHomolog.

The advantage of this mechanism is that there is no need to exchange several Urls in the system, depending on its environment: type approval or production.

Note that, the same behavior can-be obtained with variables that are not constant, however the creation of constants ensures that they are not modified by the application. Note that, this possibility of condition in your creation is not allowed after the constants are defined, which ensures their correct use by the system.

Another interesting case is the concatenation of Strings to create a constant. in previous versions of PHP, when trying to create Strings constants based on parts of other Strings, the following message is shown: "PHP Parse error". Now, this is allowed. This is exemplified in link shown in the question itself. See an example below:

// Constant declarations
const PHP = "PHP";
const LOBBY = "Lobby";
const PHPLOBBY = PHP . " " . LOBBY;
echo PHPLOBBY . "\n";
echo "\n=====================\n\n";

Note that the PHPLOBBY constant is defined by a concatenation of Strings. This is useful when constants are used in the system, but so is the concatenation of the system. In order to make the code cleaner, a constant being the result of the concatenation of several times is very useful. This type of assignment for constants is already possible, both in Java and in C# . NET.

  • Hello @Eduardofernandes! I believe that this type of use is better with a configuration file, such as application.ini of the application installation and not with the calculation of constants.

  • Hello @gpupo, note that the variable $isHomolog can stay in a. php file that can be used as settings file. Doctrine and other frameworks use this approach to retrieve database connection strings. Also the goal here is to show a possible use for Constant Scalar Expression :).

  • Eduardo, the goal is to show the ideal use and how this is used in languages where it is already mature. Using the feature to solve what is already well solved is not ideal for me. You can improve the answer!

  • I put another example

  • Thank you @Eduardofernandes. It’s not yet the expected answer because so far you’ve talked about possibilities, which is clear to us. The main issue is WHEN to use in order to improve the techniques we used before PHP 5.6, ok ?

0

Man, I’ll try to explain a good use with an example.

In the PHP code below you can see all variants of scalar expression for PHP encoding, but let’s talk about them. We have the flexibility to use this feature in "Constant declarations", "Class Constant Declarations", "Class Property Declarations", "Argument Declarations", "Static Variable Declarations". As you can see the "PHPLOBBY" in the PHP code below, it is the result of the concatenation of "PHP" and "lobby" with constant empty space between them.

if you try the same approach in previous versions of PHP will give "Parse Exception". The most important thing for me is flexibility in argument statements. We added example of the method in our "Phplobby" class called "is_true". Basically what it does is it does not pass argument that runs to "Constant Scalar Expressions" ( "$ c = self :: NUMBER == 9? "True": "False". )We check whether the constant "Number" is equal to 9 and then assign a value to the variable $ c that we have flexibility to do this only in PHP 5.6 and not in the previous version of PHP.

    <?php
echo "\n===PHPLobby Constant Scalar Expressions ===\n";

// Constant declarations
const PHP = "PHP";
const LOBBY = "Lobby";
const PHPLOBBY = PHP . " " . LOBBY;
echo PHPLOBBY . "\n";
echo "\n=====================\n\n";

// Class Constant Declarations
class PhpLobby {
    const PHP = PHP . " ";
    const LOBBY = self::PHP . LOBBY . "\n";
    const NUMBER = 5 + 4 . "\n";

    // static variable declarations
    static $math = 5 + 4 . "\n";
    static $math2 = 9 - 5 . "\n";
    static $math3 = self::NUMBER - 4 . "\n";

    // class property declarations
    public $php = "PHP " . "Lobby\n";
    public $number = 5 + 4 . "\n";

    // argument declarations
    function is_true($c = self::NUMBER == 9 ? "True" : "Wrong") {
        return $c . "\n";
    }
}
echo PhpLobby::LOBBY;
echo PhpLobby::NUMBER;
echo "\n=====================\n\n";

// Class Property Declarations
$phpLobby = new PhpLobby();
echo $phpLobby->php;
echo $phpLobby->number;
echo "\n=====================\n\n";

// Argument Declarations
echo $phpLobby->is_true(); // weeeeee magic!
echo $phpLobby->is_true(10); // result will be 10 as expected
echo "\n=====================\n\n";

// Static Variable Declarations
echo PhpLobby::$math;
echo PhpLobby::$math2;
echo PhpLobby::$math3;

echo "\n===========================================\n";
?>

Also, here is the list of what can be used with it:

Supported Operation:

    • - Addition
    • - Subtraction
    • - Multiplication
  1. / - Division
  2. % - Modulus
  3. ! - Boolean Negation
  4. ~ - Bitwise Negation
  5. | - Bitwise OR
  6. & - Bitwise AND
  7. ^ - Bitwise XOR
  8. << - Bitwise Shift Left
  9. >> - Bitwise Shift Right
  10. . - Concatenation
  11. ?: - Ternary Operator
  12. <= - Smaller or Equal
  13. => - Greater or Equal
  14. == - Equal
  15. != - Not Equal
  16. < - Smaller
  17. > - Greater
  18. === - Identical
  19. !== - Not Identical
  20. && / and - Boolean AND
  21. || / or - Boolean OR
  22. xor - Boolean XOR

Supported Operands

  1. 123 - Integers
  2. 123.456 - Floats
  3. "foo" - Strings
  4. LINE - Line Magic Constant
  5. FILE - File Magic Constant
  6. DIR - Directory Magic Constant
  7. TRAIT - Trait Magic Constant
  8. METHOD - Method Magic Constant
  9. FUNCTION - Function Magic Constant
  10. NAMESPACE - Namespace Magic Constant
  11. <<
  12. <<<'NOWDOC' - NOWDOC string syntax
  13. SOME_RANDOM_CONSTANT - Constants
  14. class_name::SOME_CONST - Class constants

And if you want to know more, go to their website: https://wiki.php.net/rfc/const_scalar_exprs

I hope I helped! Hugs!

  • hi @Dante! Thank you for the reply. If you look at the history of the question edits, you will see that this example that you used to be part of the question itself, but that we decided to remove to simplify it. You need to tell us how this functionality is used in good practice in other languages where it is already mature.

Browser other questions tagged

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