简体   繁体   中英

PHP constants conflict in different packages

Im working on an agile PHP project separated into several libraries and plugins and autoloaded with composer. the problem that i run into is that i have nearly the same config file for each library like so:

<?php

 define('ROOT', __DIR__); // root dir
 define('APP', ROOT . DS . 'app'); // app directory

Something like this in all my packages which is creating constants conflict.

So how can i do something cleaner in which each package will have its own paths and links without having any conflict with other packages as well with composer packages thanks.

You can simply solve this problem by using, namespaces and class constants .

For example:

LibA:

<?php 

namespace libraryA;

class Config
{
    const ROOT = __DIR__;
    const DS = '/';
    const APP = self::ROOT . self::DS . 'appA';
}

LibB:

<?php 

namespace libraryB;

class Config
{
    const ROOT = __DIR__;
    const DS = '/';
    const APP = self::ROOT . self::DS . 'appB';
}

Which you can access easily anywhere like this:

<?php

use libraryA\Config as AConfig;
use libraryB\Config as BConfig;


var_dump(AConfig::APP, BConfig::APP);

This way they will remain separate and and the code will be more readable.
This is just an example, you don't really have to re declare DS and ROOT for every config class. you can just use 1 parent class to contain these global constants.

There are actually three types of user-defined constant in PHP:

  • Global constants declared with define() , which have the same value in all scopes. These should be used with care, because as you've discovered, it's easy to end up with two pieces of code trying to define the same constant. You can however check if the constant already exists, if you're sure it's being used for the same purpose in both places eg if ( ! defined('MAGIC') ) { define('MAGIC', 'xyzzy'); } if ( ! defined('MAGIC') ) { define('MAGIC', 'xyzzy'); }
  • Class constants, declared with const inside a class definition, and accessed with the syntax ClassName::FOO . These are more explicitly scoped, and since the class can be autoloaded, you don't need to explicitly include a file with the definitions. The class can in turn be in a namespace, for additional separation between packages. However, there are limits on what you can define them based on, eg they can't be the result of a function call, unlike with define() .
  • Namespace constants, declared with const in a file which has a namespace declaration at the top. These can be referenced either with a fully-qualified name like Foo\\Bar\\MAGIC , or aliased in a particular file to a shorter name , using use const Foo\\Bar\\MAGIC or use const Foo\\Bar\\MAGIC as BAR_MAGIC . They save you having to create an otherwise empty class just to put your constants in, but unfortunately can't be autoloaded, so you still need to explicitly include a file to define them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM