Forum Moderators: coopster

Message Too Old, No Replies

Difference between define() and just setting a constant

         

csdude55

5:43 pm on Mar 13, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not sure if I understand the value of using define().

I have a variables.php script that I load on every page. It includes dozens of variables and functions that are used regularly, like setting paths:

$basepath = '/home/example';
$wwwpath = $basepath . '/www';

Right now I'm looking at define():

[php.net...]

Is there some value to setting this instead of just using a variable?

define('_BASEPATH_', '/home/example');
define('_WWWPATH_', _BASEPATH_ . '/www');

The only value I can see is that I wouldn't be able to accidentally overwrite the variable later, so a positive during production but at the tradeoff of having harder to read code long term.

Is there another reason I should be considering this in my scripts? I originally thought it would let me set the variable permanently without having to reset it on each page load, which would have been pretty cool since some variables would very rarely change, but I don't think that's the case.

Dimitri

5:47 pm on Mar 13, 2020 (gmt 0)

csdude55

12:57 am on Mar 14, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks, @Dimitri, that was almost (but not quite) as clear as mud... LOL

From this:

The fundamental difference between those two ways is that const defines constants at compile time, whereas define defines them at run time.

The term "compile time" throws me off, because that makes me think that it's referring to variables being set in PHP configuration and only being loaded once when PHP is compiled. But that can't be right.

I'm thinking that they differences here are:

// this variable can be changed anytime
var = 0;
if ($foo = $bar)
$var = 1;

// this can't be changed once it's set, but expressions and conditions are OK
if ($foo = $bar)
define(_VAR_, 1);

else
define(_VAR_, 0);

// this can't be changed, and can't be set in an expression
const _VAR = 1;

I can't find any real advantage to using define() or const over just setting a variable, unless there's a danger of accidentally changing the value later in the script. Is that right?

csdude55

3:20 am on Mar 14, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Egad, I'm so embarrassed... those should be if ($foo === $bar)...

csdude55

6:56 pm on Mar 14, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I did a little benchmarking...

It looks like there's a significant speed difference when writing each of these types. Running a loop of 10,000 iterations:

const = 3.19
define = 4.3
$var = 9.5

But setting another variable to the value of the constant (technically, an array value for the test; eg, $foo[$i] = _VAR_) is also significantly different:

const = 36.01
define = 35.5
$var = 2.25

So I believe that writing a constant is faster, but reading a variable is faster. Granted, when we're talking about milliseconds over 10,000 iterations this is pretty insignificant, but if you have a script that's running a lot of iterations and time matters then it's worth knowing.

As far as I can tell, "const" would be the OK choice if you're strictly setting the value to text and don't need to use any variables, conditions, or functions. An example might be:

const _BASE_ = '/home/example';

"define()" would be the OK choice if you are setting the value to anything that's variable, is in a condition, or uses a function. An example might be:

define('_DBH_', @mysqli_connect('localhost', ...));

Otherwise, using a regular variable would be the best choice. And I'm not really convinced that using const or define() would ever be the "best" choice for a normal website.

****

One other difference that I found that may be noteworthy: I can't find a way to print the value of const or define() within an EOF. So while this works:

echo _BASE_;

this does not:

echo <<<EOF
first: _BASE_
second: {_BASE_}
EOF;

Both lines in the above just show the text "_BASE_" or "{_BASE_}" instead of the value of the constant. There might be another way to get them to print them within the EOF that I didn't consider, of course.


Based on all of the above, the only use I can think of for using a constant on my website would be as DBH (like my example above). But I need to do another speedtest to find out if a series of mysqli_real_escape_string(_DBH_, $var) (for example) is faster than mysqli_real_escape_string($dbh, $var). I'm hesitant to test it on my live database, though... anybody know of a sandbox website that'll let me connect to their database and run test queries?

w3dk

9:04 pm on Mar 14, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



The linked StackOverflow question explains the difference between "const" and "define()" - that's not what you are asking here (the confusion may be in your title). You are asking the difference between using global variables and define()'d constants.

Yes, global variables (unlike "constants") can be changed / overridden.

A notable difference is the scope in which these operate... defined constants are global and available in every scope (inside functions etc.). Whereas global variables are not available inside functions (local scope) without first explicitly importing them with the "global" keyword.

Historically, define()'d constants have only supported scalar types (int, float, string, boolean). Only from PHP7+ can you assign arrays.

define('_DBH_', @mysqli_connect('localhost', ...));


I'm not even sure that would work... mysqli_connect() returns an object. (See above)

But that also looks wrong - you should be assigning the value of a function call to a variable. If it should fail, you can't retest the connection in the same request.

I can't find a way to print the value of const or define() within an EOF.


Yes, you can't directly use constants with "variable parsing". You would need to first assign it to a variable!

("within an EOF" - that's "heredoc" syntax.)


"Performance" should not be a factor here. In real world scenario's the difference is negligible. Whatever you think is the right tool for the job.

w3dk

11:08 pm on Mar 14, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



The term "compile time" throws me off, because that makes me think that it's referring to variables being set in PHP configuration and only being loaded once when PHP is compiled. But that can't be right.


By "compile time" they effectively mean when the PHP file is first loaded into memory and parsed by the PHP interpreter (converted to byte-code etc.) - You will more likely be notified of errors immediately and the file won't run.

However, define()'s are only processed "late" at runtime and can be entirely conditional - they might not be set at all. Unless there is a fatal parse error, you may not notice the error for [insert period of time], until that part of the code is actually "run".

csdude55

10:02 pm on Mar 15, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not even sure that would work... mysqli_connect() returns an object. (See above)

@w3dk, you're right, I just tested it and it gave a fatal error. So at this point I can't really think of any reason to use define() or const in my websites.

Dimitri

1:03 pm on Mar 17, 2020 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month



You use constants to set values, that you don't want to accidentally overwrite (variables).