0

So I am using vlucas/phpdotenv in my php application to store and use environment variables. I have created a db.php file which contains the configuration of my database connection. The folder structure is root/config/db.php.

I have require('../vendor/autoload.php'); in the db.php file and then I have used

$dotenv=Dotenv\Dotenv::createImmutable('../');
$dotenv->load();
print_r($_ENV);

to access the environment variables since the .env file is in the root of the directory. It all works perfectly fine when i access the db.php file on the server but when I include this file in the register.php file which is in the root I get the error "Fatal error: require(): Failed opening required '../vendor/autoload.php' (include_path='C:\xampp\php\PEAR')".

However when I change the directory of the autoload.php to match the path I then get this error: "Uncaught Dotenv\Exception\InvalidPathException: Unable to read any of the environment file(s) at [../.env]."

Can someone please help me out here? Thank you.

2 Answers2

1

It looks like you're using a relative path, but expecting it to function like an absolute path.

the ../ notation meant the parent directory, so if you move the file the parent directory changes also.

Instead of working relatively, I prefer to set a base and work upwards.

Use $_SERVER['DOCUMENT_ROOT'], which is the file path to the root of your application.

require($_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php');

Then use the same notation in you createImmutable static call. I don't know where you're supposed to be pointing that to. If it's the root, use...

$dotenv=Dotenv\Dotenv::createImmutable($_SERVER['DOCUMENT_ROOT']);
$dotenv->load();
print_r($_ENV);
hubare
  • 48
  • 6
0

So let's look at this. Your directory structure seems to be something like this:

/
|- register.php
|- login.php
|- .env
|- /config
   |- db.php 

There are several problems with this. One of them is: Files that should not be accessible by web browsers are accessible. (try to call your-domain.com/.env If you didn't protect this by a .htaccess file, then you'll leak your database information to public)

But coming back to your problem: ../ is a relative path. Relative to the file, that was the entry point for the call. Let's look at it: If you call config/db.php, then the current working directory will be config and ../ will point to the root path. If you call register.php, then the current working directory will be the root path and ../ will point to the parent directory.

You should go with something like this:

/
|- /public
   |- login.php
   |- register.php
|- .env
|- bootstrap.php
|- /conf
   |- db.php

Every file in public should include bootstrap.php, where dotenv will be executed. And instead of something like './env', you can use __DIR__/ . '.env'. There are several benefits from this:

  • You don't risk leaking sensible files/data
  • You always have the same include path and don't have to worry, from where to call this file

Drawbacks:

  • You have to configure your server to serve the public folder instead of the root directory.
Sindhara
  • 1,423
  • 13
  • 20
  • Yess that is exactly how my folder structure is right now. Is there a way i can create an access block to the .env file incase someone types in www.website.com/.env without changing the folder structure ? Also given your folder structure how would someone be blocked from accessing the .env file in the browser? Thanks for your help on this. :D Also as @hubare mentioned i was able to fix it using the $_SERVER['DOCUMENT_ROOT'] method. – MajesticOverlord Dec 11 '20 at 12:04
  • > Is there a way i can create an access block to the .env file incase someone types in www.website.com/.env Yes. You can define in your `.htaccess`, what files must not be served. (Assuming, you use Apache.) > Also given your folder structure how would someone be blocked from accessing the .env file in the browser? You would set the server's web root to `/public`. So there can't be any files outside of `/public` accessed. (If you look at any modern framework, they all have a `/public` folder) – Sindhara Dec 11 '20 at 12:26
  • >(Assuming, you use Apache.) I am actually not using Apache. I am running it on the PHP server using 'php -S localhost':XXXX.> >You would set the server's web root to /public. So there can't be any files outside of /public accessed. Oh yes that makes sense. Thanks a lot > I have noticed a lot of modern frameworks using public as their root directory. Thanks a lot for your help. – MajesticOverlord Dec 14 '20 at 21:52