Placing include files so web server and crons can access them

I am trying to make my website more secure by placing the include file I use for connecting to the database one directory above public_html. This is the code that I use:

include dirname($_SERVER['DOCUMENT_ROOT']) . '/includeFiles/DBconnect.php';

This works fine for all of my PHP files in public_html that require access to the database. However, $_SERVER is not defined in crontab and, therefore, will not be able to access the database in the same way.

My sendEmail.php file has accessed DBconnect.php in public_html for a long time, and so this was never an issue before I became security conscious… And sendEmail.php is a file that I manually run from time to time on the web front-end AND is executed using a cron each night.

So what is the best way to include files above public_html since I can’t use $_SERVER[‘DOCUMENT_ROOT’ as part of the path?

Thanks!

You could place a common ‘setup’ file in the directory above public_html that set this up for you. Then your web and cron tasks only need require this file to have the common things that both contexts need initialising.

So, if you created this file (let’s call it bootstrap.php, since that’s a commonly understood concept)

<?php
define('APP_ROOT', realpath(dirname(__FILE__)));

require APP_ROOT . "/includeFiles/DBconnect.php";

Then have your web files and cron tasks both require the bootstrap.php file and two things happen. First, you’ll have an APP_ROOT constant defined, which will provide the full system path to the directory that bootstrap.php resides in. Second, both web and cron contexts will have already included the DBconnect.php file.

If you’re using objects, you should probably try to get your head around namespacing and autoloading but this at least should give you a fix for what you need right now. :slight_smile:

Have you tried relative paths?

../include/dbconnect.php

Magic constant __DIR__ is faster.

Michael, can you elaborate a little? I’m a bit confused.

Thanks.

The magic constant __DIR__ has the path to the directory of the current file. It is equivalent to dirname(__FILE__). Using realpath() is unnecessary in this situation, the magic constants are real paths to begin with.

RavenVelvet, I tried to do what you suggested but it didn’t turn out exactly right. I started off by creating databaseBootstrap.php and put it in a directory called “includes” one level up from public_html. Here is the content:

define('APP_ROOT', (__DIR__));
require APP_ROOT . "/includes/databaseConnect.php";

Then I made a file called databaseConnect.php with the code needed to connect to my test or production database and threw in some echo statements also so I could verify it in both test and prod:

if (php_sapi_name() == ‘cgi-fcgi’) {

echo ‘Connected to production DB.’;

} else {

echo ‘Connected to test DB.’;

}

Then I made another file, databaseTest.php which according to your instructions, should require the bootstrap.php:

require dirname($_SERVER[‘DOCUMENT_ROOT’]) . ‘/includes/databaseBootstrap.php’;

However, when I run databaseTest.php in a browser, nothing happens. But it does work if I change the code to:

require dirname($_SERVER[‘DOCUMENT_ROOT’]) . ‘/includes/databaseConnect.php’;

And the results in the browser are then:

Connected to test DB.

So either I’m not understanding you, or perhaps you made a mistake in your directions? I have since copied the databaseTest.php file into several directories deep inside public_html. Each time I check the new location in the browser, it is able to successfully connect to the database.

Since everything seems to be working now by pointing to databaseConnect.php, then I am left wondering what the purpose is of databaseBootstrap.php

Please advise and thanks for all of your help!!

You learn something everyday! :smiley: Didn’t realise these magic constants were real paths to start with. Bonus! Thanks Michael.

1 Like

@busboy - the bootstrap file doesn’t work because it’s in the wrong location. If you did an ls in your application’s root directory, where the bootstrap is meant to live in this particular example, you should see something like this.

bootstrap.php
includes/
public_html/

The line define('APP_ROOT', __DIR__); should set the APP_ROOT constant to the directory that contains both the public_html and the includes folders.

If you wanted to created the file as databaseBootstrap.php inside the includes folder, then you’d need to knock off the includes segement in the second line of the bootstrap, resulting in a file that reads like this:

<?php
define('APP_ROOT', (__DIR__));
require APP_ROOT . '/databaseConnect.php';

But then the APP_ROOT constant wouldn’t really be very APP_ROOT-ish, since it’d be set as the path to the includes directory. :wink:

RavenVelvet, I got things working. Thanks for your help. One last question though. In my databaseTest.php file, I still have this one line of code:

require dirname($_SERVER[‘DOCUMENT_ROOT’]) . ‘/databaseBootstrap.php’;

As far as I know, when a crontab is run, it doesn’t have access to $SERVER variables, right?

Thanks!

Correct, in most frameworks this is achieved using a constant that is defined in the entry page like RavenVelvet posted.

I’m good to go now. Thanks everyone for your help.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.