<p>So debugging this a bit, it looks like its to do with the namespace declaration on the original template I was using for the migration. Basically when declaring <code>namespace Craft</code> this causes problems with loading the environment variables that were previously being masked by the <code>die()</code> error, as I was including Bootstrap too early.</p>

<pre><code>Uncaught Error: Class 'Craft\Dotenv' not found
</code></pre>

<p>In my case, the phpdotnev stuff is going to need to appear before including Bootstrap otherwise Craft isn't going to be able to connect to the DB.</p>

<p>Moving the vendor and environment variables stuff up before loading the bootstrap file from the Craft folder, seems to work. This a test file I have now:</p>

<pre><code>&lt;?php
namespace Craft;

// Avoid errors when running through console
$_SERVER['HTTP_HOST'] = 'example.craft.localdev';
$_SERVER['REQUEST_URI'] = '/index.php';

// Get the root dir so we can run migrations without worrying about path
$root_dir = dirname(dirname(__FILE__));

// We need to load in phpdotenv stuff before initialising bootstrap.php, otherwise you won't be able to connect to the DB
require_once($root_dir . '/vendor/autoload.php');

// If APP_SECRETS is not set, load in .env file
if (!getenv('APP_SECRETS'))
{
    $envFile = '.env';

    if (file_exists($root_dir . '/' . $envFile))
    {
        // PHP dotenv: https://github.com/vlucas/phpdotenv
        $dotenv = new \Dotenv\Dotenv($root_dir);
        $dotenv-&gt;load();
        $dotenv-&gt;required(['APP_SECRETS', 'CRAFT_ENVIRONMENT']);
    }
    else
    {
        die("$envFile does not exist.");
    }
}

// Set the Craft environment with the value set in .env
define('CRAFT_ENVIRONMENT', getenv('CRAFT_ENVIRONMENT'));

// Initialize Craft without letting it take over the whole request
$app = require $root_dir . '/craft/app/bootstrap.php';

// Set Craft to Craft Personal so we don't get any errors about Client/Pro-only components not being available
$app-&gt;getInfo()-&gt;edition = 0;

// CUSTOM CODE FOR MIGRATIONS AND OTHER CRAFT RELATED STUFF GOES BELOW THIS LINE
</code></pre>

<p>This then appears to be using the proper environment variables. I tested by editing my <code>db.php</code> file to break one of the variables being pulled from <code>secrets.json</code> to cause the DB connection error and it does appear to be work, as the try and catch statement is responding appropriately.</p>

<p>Not sure if there will be an issue not having the namespace Craft declared or not, but I appear to be able to interact with Craft through <code>$app</code> still. Would this be correct?</p>

CC BY-SA 4.0
2018-05-02T08:32:16.987Z
The namespace doesn't matter. You can include/remove whatever namespace you want as long as you include the correct classes
Robin Schambach
CC BY-SA 4.0
2018-05-02T08:33:23.653Z
@RobinSchambach OK. So looks like this is a working solution then!
James White
CC BY-SA 4.0
2018-05-02T08:35:45.963Z
I'm still not really sure what you did/changed... It finally looks like a normal `web/index.php` just without the `$app->run()` part like I suggested from the beginning. Only with the additional `$app->getInfo()->edition = 0;` part and everything after it.
Robin Schambach
CC BY-SA 4.0
2018-05-02T08:40:23.307Z
@RobinSchambach. Basically removed the `namespace Craft` from the script. Moved up the vendor/phpdotenv stuff up before including the `bootstrap.php`. I never had `$app->run()` in my script. The main problem seemed to be the `namespace Craft`, but because the environment variable stuff wasn't being loaded, it was just masking the overall issue by throwing the `die()` error within `db.php`. Basically the phpdotenv stuff won't work unless that namespace is removed. One line was causing the problem, something that was taken from the original migration script template I had used that Brad wrote.
James White
CC BY-SA 4.0
2018-05-02T08:44:07.700Z
Alright, glad you got it working. It's just a little bit strange because the default `web/index` that comes with a new Craft installation doesn't have the namespace `Craft` and loads all this stuff before the `bootstrap` is included... So it does everything you changed by default. Seems like yours was edited in some way or another.
Robin Schambach
CC BY-SA 4.0
2018-05-02T08:47:36.867Z
I had used Brad's original script for moving entries to two different channels as a starting point, that's where that namespace has come from on my attempt, but it looks like its the cause of all the issues, when trying different methods and versions, I hadn't realised that it was the problem all along!
James White
CC BY-SA 4.0
2018-05-02T08:48:57.333Z
Yeah that was for Craft 2 now you are using Craft 3, you should try to avoid mixing the code
Robin Schambach
CC BY-SA 4.0
2018-05-02T08:53:45.853Z
The final plot twist, this is a Craft 2 site! The summary of all of this thought, is basically that `namespace` declaration was a cascade of fail, but either way, thanks for the pointers, helped me debug the main problem.
James White
CC BY-SA 4.0
2018-05-02T08:16:09.273Z
2018-07-01T11:23:14.377Z
2018-07-01T11:23:14.377Z
James White
<p>I recently had to run a couple of migrations to move entries from one structure to the other, but had problems when running the migration PHP script being able to get environment variables e.g. DB and stuff in .env. In the end I temporarily replaced my <code>craft/config/db.php</code> and hard coded my DB on local so I could run the script, however this isn't really ideal but did the job. It seemed the script couldn't get the DB environment variables.</p>

<p>I'm wondering what should I be including in my bootstrap migration scripts going forward in order to utilise the environment variables properly. I used a version of the script here:</p>

<p><a href="https://craftcms.stackexchange.com/questions/4433/move-entry-from-one-structure-to-another-with-parenting/">Move entry from one structure to another with parenting</a></p>

<p>Slightly modified to take an array of ids, as well as mapping the old and new entry types as an arry, so it could be done in one go.</p>

<p>I essentially tried copying most of the beginning portion of the <code>index.php</code> like this and transplanting it into my migration script</p>

<pre><code>// Composer: https://getcomposer.org/doc/
require_once('../vendor/autoload.php');

// PHP dotenv: https://github.com/vlucas/phpdotenv
if (!getenv('APP_SECRETS'))
{
    $root_dir = dirname(dirname(__FILE__));
    if (file_exists($root_dir . '/.env'))
    {
        Dotenv::load($root_dir);
        Dotenv::required(array('APP_SECRETS', 'CRAFT_ENVIRONMENT'));
    }
}
define('CRAFT_ENVIRONMENT', getenv('CRAFT_ENVIRONMENT'));
</code></pre>

<p>However, no matter what I just got a <code>die()</code> error from <code>craft/local/db.php</code> saying the path to the file containing the DB crendentials (secrets.json) couldn't be found, so it seems the environment variables weren't available at runtime. <code>APP_SECRETS</code> is the path to the json file.</p>

<p>Any ideas, what I'm missing for environment variables to be loaded in?</p>

<p>Thanks.</p>

CC BY-SA 3.0
2018-04-27T14:41:15.190Z
Why don't you just use Craft's default `index.php` as a reference and remove the `$app->run()` part in order to not start Craft? I don't see any benefit in your way at all. You can even run Craft normally and create a migration file or start your script inside a module / plugin.
Robin Schambach
CC BY-SA 3.0
2018-04-27T14:43:03.383Z
@RobinSchambach I figured `bootstrap.php` was the preferred mechanism to do migrations like this. Given it ships with Craft.
James White
CC BY-SA 3.0
2018-04-27T14:51:00.063Z
Yeah but what is the difference between moving your `index.php` to your `bootstrap.php` and removing the `$app->run` from your `index.php`. You need most parts of the bootstrap anyway so you can't remove that much from it. Thus you can just remove the `run` function from your `index.php` and that's basically it
Robin Schambach
CC BY-SA 3.0
2018-04-27T15:27:09.663Z
I guess I never really thought about that. I came across the linked article related to migrations between two channels and thought `bootstrap.php` was preferred method, but if the same can be achieved through the content in the `index.php` and just removing the Craft app run part, I guess I can just use that!
James White
CC BY-SA 3.0
2018-04-30T23:59:51.577Z
@JamesWhite be sure and share your solution as an official answer once you get it working! :)
Brad Bell
CC BY-SA 3.0
2018-05-01T10:18:57.493Z
@BradBell Thanks. Still struggling to get ENV variables available, no matter which way I approach it, so I'm clearly missing something.
James White
CC BY-SA 4.0
2018-05-02T06:05:24.207Z
@JamesWhite did you change any paths? Did you place your folders somewhere else? Because your env file is usually loaded in your `web\index.php` `if (file_exists($root.'/.env')) {
    $dotenv = new Dotenv\Dotenv($root);
    $dotenv->load();
}`
Robin Schambach
CC BY-SA 4.0
2018-05-02T06:09:02.970Z
Yes. It looks like as soon as bootstrap is included. I just get a die response from my db.php about missing the APP_SECRETS no matter what I do. I'll debug some more to make sure the .env path is being loaded
James White
<migration><bootstrap-craft>
bootstrap.php how to include environment variables for multi-environment configuration?
# bootstrap.php how to include environment variables for multi-environment configuration?

(Asked by: username_0 on 2018-04-21)

I recently had to run a couple of migrations to move entries from one structure to the other, but had problems when running the migration PHP script being able to get environment variables e.g. DB and stuff in .env. In the end I temporarily replaced my craft/config/db.php and hard coded my DB on local so I could run the script, however this isn't really ideal but did the job. It seemed the script couldn't get the DB environment variables.
I'm wondering what should I be including in my bootstrap migration scripts going forward in order to utilise the environment variables properly. I used a version of the script here:
Move entry from one structure to another with parenting
Slightly modified to take an array of ids, as well as mapping the old and new entry types as an arry, so it could be done in one go.
I essentially tried copying most of the beginning portion of the index.php like this and transplanting it into my migration script
// Composer: https://getcomposer.org/doc/
require_once('../vendor/autoload.php');

// PHP dotenv: https://github.com/vlucas/phpdotenv
if (!getenv('APP_SECRETS'))
{
    $root_dir = dirname(dirname(__FILE__));
    if (file_exists($root_dir . '/.env'))
    {
        Dotenv::load($root_dir);
        Dotenv::required(array('APP_SECRETS', 'CRAFT_ENVIRONMENT'));
    }
}
define('CRAFT_ENVIRONMENT', getenv('CRAFT_ENVIRONMENT'));

However, no matter what I just got a die() error from craft/local/db.php saying the path to the file containing the DB crendentials (secrets.json) couldn't be found, so it seems the environment variables weren't available at runtime. APP_SECRETS is the path to the json file.
Any ideas, what I'm missing for environment variables to be loaded in?
Thanks.

**Tags:** migration, bootstrap-craft

> **Comments:**
> **username_1**: Why don't you just use Craft's default `index.php` as a reference and remove the `$app->run()` part in order to not start Craft? I don't see any benefit in your way at all. You can even run Craft normally and create a migration file or start your script inside a module / plugin.  
> **username_0**: @RobinSchambach I figured `bootstrap.php` was the preferred mechanism to do migrations like this. Given it ships with Craft.  
> **username_1**: Yeah but what is the difference between moving your `index.php` to your `bootstrap.php` and removing the `$app->run` from your `index.php`. You need most parts of the bootstrap anyway so you can't remove that much from it. Thus you can just remove the `run` function from your `index.php` and that's basically it  
> **username_0**: I guess I never really thought about that. I came across the linked article related to migrations between two channels and thought `bootstrap.php` was preferred method, but if the same can be achieved through the content in the `index.php` and just removing the Craft app run part, I guess I can just use that!  
> **username_2**: @JamesWhite be sure and share your solution as an official answer once you get it working! :)  
> **username_0**: @BradBell Thanks. Still struggling to get ENV variables available, no matter which way I approach it, so I'm clearly missing something.  
> **username_1**: @JamesWhite did you change any paths? Did you place your folders somewhere else? Because your env file is usually loaded in your `web\index.php` `if (file_exists($root.'/.env')) {     $dotenv = new Dotenv\Dotenv($root);     $dotenv->load(); }`  
> **username_0**: Yes. It looks like as soon as bootstrap is included. I just get a die response from my db.php about missing the APP_SECRETS no matter what I do. I'll debug some more to make sure the .env path is being loaded  

---

## 1 answers

### Answer by username_0 on 2018-05-02. Score: 1

So debugging this a bit, it looks like its to do with the namespace declaration on the original template I was using for the migration. Basically when declaring namespace Craft this causes problems with loading the environment variables that were previously being masked by the die() error, as I was including Bootstrap too early.
Uncaught Error: Class 'Craft\Dotenv' not found

In my case, the phpdotnev stuff is going to need to appear before including Bootstrap otherwise Craft isn't going to be able to connect to the DB.
Moving the vendor and environment variables stuff up before loading the bootstrap file from the Craft folder, seems to work. This a test file I have now:
load();
        $dotenv->required(['APP_SECRETS', 'CRAFT_ENVIRONMENT']);
    }
    else
    {
        die("$envFile does not exist.");
    }
}

// Set the Craft environment with the value set in .env
define('CRAFT_ENVIRONMENT', getenv('CRAFT_ENVIRONMENT'));

// Initialize Craft without letting it take over the whole request
$app = require $root_dir . '/craft/app/bootstrap.php';

// Set Craft to Craft Personal so we don't get any errors about Client/Pro-only components not being available
$app->getInfo()->edition = 0;

// CUSTOM CODE FOR MIGRATIONS AND OTHER CRAFT RELATED STUFF GOES BELOW THIS LINE

This then appears to be using the proper environment variables. I tested by editing my db.php file to break one of the variables being pulled from secrets.json to cause the DB connection error and it does appear to be work, as the try and catch statement is responding appropriately.
Not sure if there will be an issue not having the namespace Craft declared or not, but I appear to be able to interact with Craft through $app still. Would this be correct?

> **Comments:**
> **username_1**: The namespace doesn't matter. You can include/remove whatever namespace you want as long as you include the correct classes  
> **username_0**: @RobinSchambach OK. So looks like this is a working solution then!  
> **username_1**: I'm still not really sure what you did/changed... It finally looks like a normal `web/index.php` just without the `$app->run()` part like I suggested from the beginning. Only with the additional `$app->getInfo()->edition = 0;` part and everything after it.  
> **username_0**: @RobinSchambach. Basically removed the `namespace Craft` from the script. Moved up the vendor/phpdotenv stuff up before including the `bootstrap.php`. I never had `$app->run()` in my script. The main problem seemed to be the `namespace Craft`, but because the environment variable stuff wasn't being loaded, it was just masking the overall issue by throwing the `die()` error within `db.php`. Basically the phpdotenv stuff won't work unless that namespace is removed. One line was causing the problem, something that was taken from the original migration script template I had used that Brad wrote.  
> **username_1**: Alright, glad you got it working. It's just a little bit strange because the default `web/index` that comes with a new Craft installation doesn't have the namespace `Craft` and loads all this stuff before the `bootstrap` is included... So it does everything you changed by default. Seems like yours was edited in some way or another.  
> **username_0**: I had used Brad's original script for moving entries to two different channels as a starting point, that's where that namespace has come from on my attempt, but it looks like its the cause of all the issues, when trying different methods and versions, I hadn't realised that it was the problem all along!  
> **username_1**: Yeah that was for Craft 2 now you are using Craft 3, you should try to avoid mixing the code  
> **username_0**: The final plot twist, this is a Craft 2 site! The summary of all of this thought, is basically that `namespace` declaration was a cascade of fail, but either way, thanks for the pointers, helped me debug the main problem.  

---

