Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:32:16.987Z
Answers.Text: The namespace doesn't matter. You can include/remove whatever namespace you want as long as you include the correct classes
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:33:23.653Z
Answers.Text: @RobinSchambach OK. So looks like this is a working solution then!
Answers.UserDisplayName: James White
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:35:45.963Z
Answers.Text: 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.
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:40:23.307Z
Answers.Text: @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.
Answers.UserDisplayName: James White
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:44:07.700Z
Answers.Text: 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.
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:47:36.867Z
Answers.Text: 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!
Answers.UserDisplayName: James White
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:48:57.333Z
Answers.Text: Yeah that was for Craft 2 now you are using Craft 3, you should try to avoid mixing the code
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:53:45.853Z
Answers.Text: 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.
Answers.UserDisplayName: James White
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-02T08:16:09.273Z
Answers.LastActivityDate: 2018-07-01T11:23:14.377Z
Answers.LastEditDate: 2018-07-01T11:23:14.377Z
Answers.UserDisplayName: James White
Body: <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>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-04-27T14:41:15.190Z
Comments.Text: 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.
Comments.UserDisplayName: Robin Schambach
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-04-27T14:43:03.383Z
Comments.Text: @RobinSchambach I figured `bootstrap.php` was the preferred mechanism to do migrations like this. Given it ships with Craft.
Comments.UserDisplayName: James White
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-04-27T14:51:00.063Z
Comments.Text: 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
Comments.UserDisplayName: Robin Schambach
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-04-27T15:27:09.663Z
Comments.Text: 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!
Comments.UserDisplayName: James White
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-04-30T23:59:51.577Z
Comments.Text: @JamesWhite be sure and share your solution as an official answer once you get it working! :)
Comments.UserDisplayName: Brad Bell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2018-05-01T10:18:57.493Z
Comments.Text: @BradBell Thanks. Still struggling to get ENV variables available, no matter which way I approach it, so I'm clearly missing something.
Comments.UserDisplayName: James White
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-05-02T06:05:24.207Z
Comments.Text: @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();
  }`
Comments.UserDisplayName: Robin Schambach
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-05-02T06:09:02.970Z
Comments.Text: 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
Comments.UserDisplayName: James White
Tags: <migration><bootstrap-craft>
Title: bootstrap.php how to include environment variables for multi-environment configuration?
ThreadText: # 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](https://craftcms.stackexchange.com/questions/4433/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**: @username_1 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**: @username_0 be sure and share your solution as an official answer once you get it working! :)  
  > **username_0**: @username_2 Thanks. Still struggling to get ENV variables available, no matter which way I approach it, so I'm clearly missing something.  
  > **username_1**: @username_0 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:
  
  ```
  <?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->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**: @username_1 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**: @username_1. 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 username_2 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 username_2'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.  
  
  ---
  
  