To add phpdotenv, I am supposed to run the following terminal command:
composer require vlucas/phpdotenv
But I’m not exactly sure which folder I should be running the command.
My folder structure looks like this:
SITE
--> www
--> css
--> include
- database.php
- index.php
docker-compose.yml
dockerfile
When I run the composer command from the main SITE folder, it creates a folder called Vendor, as well as a composer.json file looks like this:
{
"require": {
"vlucas/phpdotenv": "^5.6"
}
}
So now the structure looks like this:
SITE
--> www
--> css
--> include
- database.php
- index.php
--> vendor
- composer.json
- composer.lock
- docker-compose.yml
- dockerfile
So now I can create a .env file within my www folder with the other webfiles, which looks like this:
DATABASE_HOST=db
DATABASE_NAME=myDb
DATABASE_USER=user
DATABASE_PASS=test
So in my database.php file, I try to pass the info from my .env file:
<?php
require __DIR__ . "/vendor/autoload.php";
$dotenv = DotenvDotenv::createImmutable(__DIR__);
$dotenv->load();
$dbhost = $_ENV["DATABASE_HOST"];
$dbname = $_ENV["DATABASE_NAME"];
$dbuser = $_ENV["DATABASE_USER"];
$dbpass = $_ENV["DATABASE_PASS"];
try{
$dbc = new PDO("mysql:dbname=$dbname;host=$host;port=3306;user=$dbuser;pass=$dbpass");
$dbc->SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Conneciton failed: " . $e->getMessage() . "<br/>";
}
?>
After doing all of the above, I am getting the below error:
Warning: require(/var/www/html/include/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/include/database.php on line 2
Fatal error: require(): Failed opening required '/var/www/html/include/vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/html/include/database.php on line 2
I tried adjusting the vendor path in the database.php file, but I still get the same error.
I tried running the composer command inside the www folder, but I still get the same error.
What did I do wrong and how do I fix it?
2
Answers
Since database.php is in the includes directory you need to go back a level in your require statement to get to the vendor directory, like this:
require __DIR__ . "/../vendor/autoload.php";
Some notes in no particular order:
It’s very hard to maintain your PHP dependencies as individual Docker commands. Why don’t you just commit
composer.json
and (important)composer.lock
files and only runcomposer install
from Docker?You run Composer commands wherever you want
vendor
directory to be. PHP doesn’t care about such location, as long as the PHP process has permission to read the directory (and Composer process has permission to write it). It’s typically a bad idea to make the directory public, so don’t publish it under your web server document root (I guess it’s/SITE/www
in your case), but the same can be generally said about most regular PHP code (/SITE/www/include
is not a good location).Calling
autoload.php
from every source file is not wrong but it kind of defeats the convenience of having a class auto-loader. Why don’t you call it in your index file?__DIR__
is the directory of the file where you physically write it, it doesn’t have anything to do with your project or document root.Don’t catch exceptions to demote them to regular program output. Doing so you’re killing error reporting features. If you don’t know what to do with them, the best approach is to do nothing.
Do one thing at a time. First ensure you can load the library and make it work with your code, then take care of Docker automation.