111

I am rather new to laravel. I have a basic question, What is the best way to add constants in laravel. I know the .env method that we use to add the constants. Also I have made one constants file to use them for my project. For example:

define('OPTION_ATTACHMENT', 13);
define('OPTION_EMAIL', 14);
define('OPTION_MONETERY', 15);
define('OPTION_RATINGS', 16);
define('OPTION_TEXTAREA', 17);

And so on. It can reach upto 100 or more records. So What should be the best approach to write the constants. The .env method. Or adding the constant.php file?

Thanks

Faran Khan
  • 1,495
  • 4
  • 14
  • 26
  • 1
    you can choose a lot of places: 1) a regular (my)SQL db 2) a key-value story / nosql db like redis 3) the config folder, using your own config file and probably many more. Best practice would be probably option 3 and also the fastest – online Thomas Feb 10 '17 at 09:28
  • Maybe this answer can be useful for you :http://stackoverflow.com/a/26062788/6028607 – Vincent G Feb 10 '17 at 09:29
  • @VincentG like I have explained above. I dont think .env is the best choice. I have a long list of constants. – Faran Khan Feb 10 '17 at 10:33
  • Possible duplicate of [Laravel: Where to store global arrays data and constants?](https://stackoverflow.com/questions/26854030/laravel-where-to-store-global-arrays-data-and-constants) – Stack Programmer Apr 25 '19 at 10:13
  • 2
    Your accepted answer does not align with your question or example. A constant is not a config variable that will change. It is exactly how it is labeled, a constant value that does not change no matter what. The answer given by @Neekobus is the correct approach for constants. You may want to revise the accepted answer. – John C Sep 11 '20 at 15:01

12 Answers12

180

For most constants used globally across the application, storing them in config files is sufficient. It is also pretty simple

Create a new file in the config directory. Let's call it constants.php

In there you have to return an array of config values.

return [
    'options' => [
        'option_attachment' => '13',
        'option_email' => '14',
        'option_monetery' => '15',
        'option_ratings' => '16',
        'option_textarea' => '17',
    ]
];

And you can access them as follows

config('constants.options');
// or if you want a specific one
config('constants.options.option_attachment');
Adam
  • 25,960
  • 22
  • 158
  • 247
K Arun Singh
  • 2,629
  • 3
  • 20
  • 34
  • 1
    the directory is actually `/config` – online Thomas Feb 10 '17 at 09:32
  • 4
    @KArunSingh why didnt you just point to duplicate https://stackoverflow.com/questions/26854030/laravel-where-to-store-global-arrays-data-and-constants . – blamb Aug 10 '17 at 17:16
  • 3
    `in mathematics, the adjective constant means non-varying` which means this is not the "correct answer" – naT erraT Nov 03 '17 at 20:09
  • 18
    remember to run `php artisan config:cache` after adding the constants.php file – elijah7 Nov 07 '17 at 15:54
  • 3
    Also I think it should be `\Config::get('constants.options');` or `\Config::get('constants.options.option_attachment');` with backslash – Pedro Luz Jan 25 '18 at 10:57
  • Either use `\Config::get` or write on top of the class `use Config` – Adam May 15 '18 at 10:13
  • 7
    One can also call it with the `config` helper `config('constants.options');` – Adam Sep 14 '18 at 07:03
  • 1
    If I'm understanding the question, you're not asking about configuration variables. You're asking about defining constants which are a way to remove magic numbers and strings https://stackoverflow.com/a/3518945/3738956 from your code. I don't think the config files are a place to do this. I recommend the answer by @Neekobus https://stackoverflow.com/a/50276442/3738956 of using "Aliased class constants" I think they fit your question much better. – tsdorsey Oct 31 '19 at 18:33
  • Instead of using "::get()", just use config('constants.options') or config('constants.options.option_attachment'); Make sure in the above solutions I have not used first letter capital with "::get()". – Amzad Khan Oct 11 '20 at 16:49
118

I use aliased class constants :

First, create your class that contain your constants : App/MyApp.php for exemple

namespace App;

class MyApp {
   const MYCONST = 'val';
}

Then add it to the aliased classes in the config/app.php

'aliases' => [
  //...
  'MyApp' => App\MyApp::class,

Finally use them wherever you like (controllers or even blades) :

MyApp::MYCONST
Neekobus
  • 1,870
  • 1
  • 14
  • 18
  • 2
    I like this approach. This will help other developers to easily track where constants are coming from instead of declaring it to your auto load. Is there any drawback of using this approach? – SMPLYJR Oct 29 '19 at 01:33
  • 1
    For constants, I can't see any drawbacks. For config (changing with environment) is not fitted. Use Config:get instead. – Neekobus Oct 30 '19 at 10:46
  • 2
    This is a better and faster option than the "accepted answer" thanks! – gtamborero May 23 '20 at 21:23
  • like that approach as well (just remind of using `composer dump-autoload` after the changes – heavyrick Aug 20 '20 at 16:49
  • Does all of this still hold true in Laravel (currently v9)? Would you still put it in the root of `app`? With the subfolders of `Console`, `Exceptions`, `Http`, `Providers`, `Services`, & `View`, none really seem to apply?!? – wruckie Nov 03 '22 at 02:31
  • 1
    @wruckie Typically people will make a subfolder under `app` called `Support` for this type of stuff. – Ryan Mortier Nov 04 '22 at 15:43
  • I was able to get code like this running in Views, but not in my Controllers. I had to use `using App\MyConst` class import. Is that normal? That does not agree with @Neekobus last statement. – wruckie Nov 04 '22 at 21:04
20

Your question was about the 'best practices' and you asked about the '.env method'.

.env is only for variables that change because the environment changes. Examples of different environments: test, acceptance, production.

So the .env contains database credentials, API keys, etc.

The .env should (imho) never contain constants which are the same over all environments. Just use the suggested config files for that.

redcenter
  • 826
  • 4
  • 10
17

First you make Constants folder inside your app directory.

And then you make Constants.php. Define your constants in this file

For Example :

define('ONE', '1');
define('TWO', '2');

And you modify the composer.json

Alternatively, you can use composer.json to load the bootstrap/constants.php file by adding the following code to the “autoload” section, like so:

"autoload": {
    "files": [
        "bootstrap/constants.php"
    ]
}

And update your composer !

Hax0r
  • 1,722
  • 4
  • 25
  • 43
17

You can create a file named paths.php in root directory/config/paths.php

Insert this data into paths.php

define('OPTION_ATTACHMENT', 13);
define('OPTION_EMAIL', 14);
define('OPTION_MONETERY', 15);
define('OPTION_RATINGS', 16);
define('OPTION_TEXTAREA', 17);

Note : make sure to run command : php artisan config:clear

Dev Semicolon
  • 444
  • 3
  • 11
14

I think you should not have a single place for all your constants. Especially no file called constance.php.

I use PHP constance in classes and refer to them in code, so its more readable, typically to avoid magic numbers and typos in strings

Car::where('car_type','=', 'fast_car')->get();

and rather have

Car::where('car_type','=', CarType::FAST)->get();

If its a value that depends on your environment (like email setting, should be different local vs production), then you should add it to a matching files in the config folder (e.g. '/config/mail.php'). You may also just add a new file in the config folder. A config file returns an array, so it could look like this:

<?php

return [
  'your_option' => env('YOUR_OPTION')
];

and you can read it using the config helper:

config('your_config_file.your_option');

Its important to never call the env function outside a configuration file, as the env function returns null outside a configuration file when cache is enabled.

If the option does not rely on your environment, you can just add it directly to the matching config file.

<?php

return [
  'your_option' => 10
];
Adam
  • 25,960
  • 22
  • 158
  • 247
14

I would personally create a class for that.

<?php

namespace App\Transaction\Constants;

/**
 * Class TransactionTypeConstant.
 */
final class TransactionTypeConstant
{
    public const TYPE_CREDIT = 'CREDIT';
    public const TYPE_DEBIT = 'DEBIT';
}

and use it like this:

<?php

namespace App\Transaction;

use App\Transaction\Constants\TransactionTypeConstant;

class Transaction
{
    /**
     * Execute the task.
     *
     * @return object
     */
    public function run()
    {
        if ($transaction->type === TransactionTypeConstant::TYPE_DEBIT) {
            //do something
        }
    }
}
Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
berusjamban
  • 323
  • 4
  • 12
11

Another way as following:

  1. create the constant.php file in app/config directory
  2. in composer.json file, add the directives like this:

    "autoload": {
       "classmap": [
           "database/seeds",
           "database/factories"
       ],
       "psr-4": {
           "App\\": "app/"
       },
       "files": [
           "app/helpers.php",
           "app/config/constants.php"
       ]
    }
    
Khaldoun Nd
  • 1,436
  • 12
  • 23
yangwendaxia
  • 179
  • 2
  • 7
2

You can simply do this:

  1. Put your constants to 'config/app.php' on main array, like:

    'CONSTANT_NAME' => 'CONSTANT_VALUE',
    
  2. Use them where ever you want with:

    {{ Config::get('CONSTANT_NAME') }} 
    
Bioukh
  • 1,888
  • 1
  • 16
  • 27
Mehran Nasr
  • 157
  • 8
2

You can define constants at the top of the web.php file located in routes and can be access the constants anywhere in project with just constant name

define('OPTION_ATTACHMENT', 13);
define('OPTION_EMAIL', 14);
define('OPTION_MONETERY', 15);
define('OPTION_RATINGS', 16);
define('OPTION_TEXTAREA', 17);
Naeem Ijaz
  • 805
  • 9
  • 17
0
require app_path().'/constants.php';

define('ADMIN',  'administrator');

or -

You can also move more sensitive info

return [
   'hash_salt' => env('HASH_SALT'),
 ];

And use it like before:

 echo Config::get('constants.hash_salt');
Yahya Ayyoub
  • 322
  • 2
  • 10
0

i think best way to define constant using a helper file. check my solution.

Define file path in composer.json

   "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "files": [
            "app/helpers.php",
            "app/Helper/function.php"  // constant defined here
        ],

app/Helper/function.php

define("assetPath","UI/");
define("viewPath","UI/");

use this constant anywhere in project. i am using in blade file.

  <script src="{{asset(assetPath.'js/jquery.min.js')}}"></script>
  <script src="{{asset(assetPath.'js/popper.min.js')}}"></script>
  <script src="{{asset(assetPath.'js/bootstrap.min.js')}}"></script>

my approach is better than this

Config::get('constants.options');
Config::get('constants.options.option_attachment');

here another problem is this , you have to run cache:clear or cache command for this. but my approach not required this.

pankaj
  • 1
  • 17
  • 36