19

Stupid question - I'm surprised this one has bitten me. Why do undefined constants in PHP evaluate to true?

Test case:

<?php
    if(WHATEVER_THIS_ISNT_DEFINED)
        echo 'Huh?';
?>

The above example prints 'Huh?'

Thanks so much for your help! :)

hakre
  • 193,403
  • 52
  • 435
  • 836
rinogo
  • 8,491
  • 12
  • 61
  • 102
  • Wow, PHP surprises again. Probable reason: "because it doesn't evaluate to false" :) – Rekin Jun 01 '11 at 20:10
  • 8
    Nope, no surprises. The warning explains everything, "Notice: Use of undefined constant MY_CONST - assumed 'MY_CONST' in some_script.php on line 5". Develop with notices and warnings turned on! :) – Chris Baker Jun 01 '11 at 20:13
  • 1
    Keep the [PHP loose comparisons](http://php.net/manual/en/types.comparisons.php#types.comparisions-loose) in mind for why `"WHATEVER_THIS_ISNT_DEFINED" == TRUE`. – Christopher Manning Jun 01 '11 at 21:07

7 Answers7

26

Try defined('WHATEVER_THIS_ISNT_DEFINED')

When PHP encounters a constant that is not defined, it throws an E_NOTICE, and uses the constant name you've tried to use as a string. That's why your snippet prints Huh!, because a non-empty string (which is not "0") will evaluate to true.

From the manual:

If you use an undefined constant, PHP assumes that you mean the name of the constant itself, just as if you called it as a string (CONSTANT vs "CONSTANT"). An error of level E_NOTICE will be issued when this happens.

If you set your error reporting level to report E_NOTICEs, which is a good practice during development, you will also see the notice thrown.

kapa
  • 77,694
  • 21
  • 158
  • 175
7

From the manual:

If you use an undefined constant, PHP assumes that you mean the name of the constant itself, just as if you called it as a string (CONSTANT vs "CONSTANT").

Basically, if WHATEVER_THIS_ISNT_DEFINED isn't defined, PHP interprets it as "WHATEVER_THIS_ISNT_DEFINED". Non-empty strings evaluate to true, so your expression will always pass (unless WHATEVER_THIS_ISNT_DEFINED is defined and set to a falsey value.)

This is, frankly, stupid behaviour. It was implemented, I believe, to allow things like $foo[bar] to work when the programmer should have used $foo['bar']. It's illogical behaviour like this that makes people think PHP isn't a real programming language.

The way to test whether a constant is defined is with defined.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
2

Undefined constants are treated as strings by PHP: docs. Taking that fact, think it through in English language:

If "WHATEVER_THIS_ISNT_DEFINED", then do something.

... it is logical that it is "true" - you aren't comparing anything to anything else.

That is why, when doing if statements, it is best practice to include a specific evaluation. If you're checking for false, put it in the code: if (something === false) vs if (something). If you're checking to see if it is set, use isset, and so on.

Also, this highlights the importance of developing with notices and warnings enabled. Your server will throw a notice for this issue:

Notice: Use of undefined constant MY_CONST - assumed 'MY_CONST' in some_script.php on line 5

Turn on notices and warnings to develop, turn them off for production. Can only help!

Chris Baker
  • 49,926
  • 12
  • 96
  • 115
2

Try defined(). If it's not defined then the constant assumes it's simply text.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
Nev Stokes
  • 9,051
  • 5
  • 42
  • 44
1

Note that constant name must always be quoted when defined.

e.g.

  • define('MY_CONST','blah') - correct
  • define(MY_CONST,'blah') - incorrect

also

<?php
 if (DEBUG) {
    // echo some sensitive data.
 }
 ?>
 and saw this warning:
 "Use of undefined constant DEBUG - assumed 'DEBUG'"

A clearer workaround is to use
 <?php
 if (defined('DEBUG')) {
    // echo some sensitive data.
 }
 ?>

See http://php.net/manual/en/language.constants.php

kapa
  • 77,694
  • 21
  • 158
  • 175
tofutim
  • 22,664
  • 20
  • 87
  • 148
0

Old question, but in addition to defined() you can also use strict type checking using ===

<?php
if(WHATEVER_THIS_ISNT_DEFINED === true) // Or whatever type/value you are trying to check
    echo 'Huh?';
Robert Dundon
  • 1,081
  • 1
  • 11
  • 22
0

It's not just constants, it is a much broader issue with PHP's parsing engine. (You ought to see warnings in your logs.)

In PHP, "bare words" that it doesn't recognize are generally treated as strings that happen to be missing their quotes, and strings with a non-zero length tend to evaluate to true.

Try this:

$x =  thisisatest ;
$y = "thisisatest";
if($x == $y){
    echo("They are the same");
}

You should see "They are the same".

Darien
  • 3,482
  • 19
  • 35
  • It is not a broader issue, it only applies to constants (which are basically bare words). In your example `thisisatest` is an undefined constant. It is only a naming convention to use uppercase letters for constants. – kapa Jun 02 '11 at 06:16