5

PHP7 brought possibility define array constants with define(). In PHP 5.6, they could only be defined with const.

So I can use define( string $name , mixed $value )) to set array of constants, but it seems that it forgot to bring also upgrade of defined ( mixed $name ) along since it still only accepts string value or am I missing something?

PHP v: < 7 I had to define every animal separately define('ANIMAL_DOG', 'black');, define('ANIMAL_CAT', 'white'); etc. or serialize my zoo.

PHP v: >= 7 I can define entire zoo which is freaking awesome, but I can't find my animal in the zoo as simply I can find single ANIMAL. It is reasonable in the real world, but here's supplementary question if I haven't miss something.

Is that intentional that defined(); does not accept array?. If I define my zoo...

define('ANIMALS', array(
    'dog' => 'black',
    'cat' => 'white',
    'bird' => 'brown'
));

... why can't I find my dog simply defined('ANIMALS' => 'dog');?

1. Prints always: The dog was not found

print (defined('ANIMALS[dog]')) ? "1. Go for a walk with the dog\n" : "1. The dog was not found\n";

2. Prints always: The dog was not found and when dog really does not exist shows Notice + Warning

/** if ANIMALS is not defined
  * Notice:  Use of undefined constant ANIMALS - assumed ANIMALS...
  * Warning:  Illegal string offset 'dog'
  * if ANIMALS['dog'] is defined we do not get no warings notices
  * but we still receive The dog was not found */
print (defined(ANIMALS['dog'])) ? "2. Go for a walk with the dog\n" : "2. The dog was not found\n";

3. regardless of whether the ANIMALS, ANIMALS['dog'] is defined or not, I get Warning:

/* Warning:  defined() expects parameter 1 to be string, array given...*/  
print defined(array('ANIMALS' => 'dog')) ? "3. Go for a walk with the dog\n" : "3. The dog was not found\n";

4. I get Notice if ANIMALS['dog'] is not defined

/* Notice: Use of undefined constant ANIMALS - assumed 'ANIMALS' */
print (isset(ANIMALS['dog'])) ? "4. Go for a walk with the dog\n" : "4. The dog was not found\n";

5. So am I correct that there is only one option left then?

print (defined('ANIMALS') && isset(ANIMALS['dog'])) ? "Go for a walk with the dog\n" : "The dog was not found\n";
8
  • 2
    Well ANIMALS is the constant; and the array key dog is simply part of the value that is defined for that constant; so it seems logical that defined() won't check for a value within the constant, only for the constant itself; so yes, logically this should be a two step check Commented Feb 13, 2016 at 12:12
  • @Mark Well for me that seems logical only in extent as PHP v < 7 define should only accept string ;) Commented Feb 13, 2016 at 12:16
  • PHP <7 would accept any scalar, not just string; but to check the type and whether it was defined was still a 2-step process.... define('TESTMODE', true); if (defined('TESTMODE') && TESTMODE) { ... } Commented Feb 13, 2016 at 12:21
  • 4
    The principle still holds it isn't ANIMALS['dog'] that's defined as the constant, it's ANIMALS.... the fact that a constant is defined doesn't tell you anything about the value of that constant, simply the fact that it is defined..... you always have (and likely always will) need to make two separate tests, one for whether the constant (name) is defined, and another to identify facets of the value of the constant.... there isn't any shortcut to do both tests in a single call.... Commented Feb 13, 2016 at 12:32
  • 1
    I guess what you want is an equivalent of isset for constants which works like isdefined(ANIMALS['dog']), and the answer is it doesn't exist at the moment. You can easily implement it as userspace function, and you can suggest it to the PHP dev team for implementation if you're convinced it's an oversight. Commented Feb 13, 2016 at 14:46

1 Answer 1

10

PHP 7 allows you to define a constant array, but what is being defined as a constant in that case is the array itself, not its individual elements. In every other regard the constant functions as a typical array, so you'll need to use conventional methods to test for the existence of a specific key within it.

Try this:

define('ANIMALS', array(
    'dog'  => 'black',
    'cat'  => 'white',
    'bird' => 'brown'
));

print (defined('ANIMALS') && array_key_exists('dog', ANIMALS)) ?
    "Go for a walk with the dog\n" : "The dog was not found\n";
Sign up to request clarification or add additional context in comments.

1 Comment

That would indeed right to use when you expect ANIMALS to be array as key => val pair, however if you have define('ANIMALS', array('dog','cat','bird')); you can't use array_key_exists and could only use option 5 isset or in_array instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.