user1677543
user1677543

Reputation:

Php define() Constants Inside Namespace Clarification

As the title states, I would really like to clarify this. I have read a few articles and postings here on this topic, something just isn't clicking for me. I'll add I'm a bit new to Php. OK, here's what I want to understand;

namespace Information;
define('ROOT_URL', 'information/');
define('OFFERS_URL', ROOT_URL . 'offers/');

namespace Products;
define('ROOT_URL', 'products/');
define('OFFERS_URL', ROOT_URL . 'offers/');

I want the constants to be constructable, ie, build constants from base constant(s), that's why I'm using define('NAME', value);.

My question being, will the value of ROOT_URL yield the value relative to its' namespace? Like this;

$info_offers_url = \Information\OFFERS_URL;  ('information/offers/')
$prod_offers_url = \Products\OFFERS_URL;     ('products/offers/')

Or does define(); place ROOT_URL in a global scope, hence I shouldn't do this? Is there a better practice?

All help is very much appreciated.

Upvotes: 34

Views: 19988

Answers (3)

David Kariuki
David Kariuki

Reputation: 1756

define() will define constants exactly as specified.

Basic knowledge: To define a constant in a namespace, you have to specify the namespace in your call to define(), even if you’re calling define() from within a namespace.

The following examples will make it clear.

The following code will define the constant MESSAGE in the global namespace (i.e. \MESSAGE).

<?php
    namespace test;
    define(‘MESSAGE’, ‘Hello world!’);
?>

The following code will define two constants in the “test” namespace.

<?php
    namespace test;
    define(‘test\HELLO’, ‘Hello world!’);
    define(__NAMESPACE__ . ‘\GOODBYE’, ‘Goodbye cruel world!’);
?>

Use it in space

namespace Product;
use const test\HELLO;

Upvotes: 2

Aravind.HU
Aravind.HU

Reputation: 9472

If you want to define a constant in a namespace, you will need to specify the namespace in your call to define(), even if you're calling define() from within a namespace. The following examples which I tried will make it clear.

The following code will define the constant "CONSTANTA" in the global namespace (i.e. "\CONSTANTA").

<?php
namespace mynamespace;
define('CONSTANTA', 'Hello A!');
?>

if you want to define constant for a namespace you can define like

<?php
namespace test;
define('test\HELLO', 'Hello world!');
define(__NAMESPACE__ . '\GOODBYE', 'Goodbye cruel world!');
?>

Otherwise, you can use const to define a constant in the current namespace:

<?php

namespace NS;

define('C', "I am a constant");
const A = "I am a letter";

echo __NAMESPACE__, , PHP_EOL; // NS
echo namespace\A, PHP_EOL; // I am a letter
echo namespace\C, PHP_EOL; // PHP Fatal error:  Uncaught Error: Undefined constant 'NS\C'

Taken from the Manual

Upvotes: 57

jawira
jawira

Reputation: 4598

Using namespaced constants is fairly easy but you must use const keyword.

Then you can directly call the constant using backslash \:

namespace Dummy\MyTime;
const MONTHS = 12;
const WEEKS = 52;
const DAYS = 365;


namespace Test;
use Dummy\MyTime;

$daysPerWeek = MyTime\DAYS / MyTime\WEEKS;
$daysPerMonth = MyTime\DAYS / MyTime\MONTHS;

echo "Days per week: $daysPerWeek\n"; // 7.0192307692308
echo "Days per month: $daysPerMonth\n"; // 30.416666666667

I think this is cleaner than using define.

Having said that, what you want (assign a scalar expression to a constant) will work only if you are using PHP >= 5.6:

namespace Information;
const ROOT_URL = 'information/';
const OFFERS_URL = ROOT_URL . 'offers/';

namespace Products;
const ROOT_URL = 'products/';
const OFFERS_URL = ROOT_URL . 'offers/';

namespace Test;
$info_offers_url = \Information\OFFERS_URL; // information/offers/
$prod_offers_url = \Products\OFFERS_URL;    // products/offers/

I hope this will help you.

Source: http://php.net/manual/en/migration56.new-features.php

Upvotes: 19

Related Questions