I keep getting confused when trying to include files that will have different paths in a local environment vs production.
For example, I have this in my usercontroller.php
file:
require_once(__DIR__ . '/config.php');
On my local host, usercontroller.php
is located in www/myproject/inc/
and config.php
is in www/myproject/
(the project root directory)
This fails.
All I want is a way to define the projects root. i.e on localhost it's www/projectname
and in productions it's /
Since files are located inside the projectname
directory on my localhost, it's causing issues on my production server.
What is the best way to simply define a base path and build my require_once
from that?
i.e. require_once($basePath . 'inc/filename.php'
Most projects use a config.inc.php
file located in a common place where these things can be defined.
config.inc.php
define('ROOT_FOLDER', '/');
define('APPLICATION_LINK', 'http://www.example.com/mysite');
script.php
require ('../config.inc.php');
echo '<a href="' . APPLICATION_LINK . '">Go home</a>';
Every project should contain a config.php file that holds this information.
config.php
define('ENVIRONMENT', 'PRODUCTION');
// define('ENVIRONMENT', 'TESTING');
// define('ENVIRONMENT', 'DEVELOPMENT');
switch (ENVIRONMENT) {
case 'PRODUCTION':
define('BASE_URL', 'http://www.mysite.com');
define('BASE_PATH', '/');
break;
case 'TESTING':
define('BASE_URL', 'http://test.mysite.com');
define('BASE_PATH', '/test/');
break;
case 'DEVELOPMENT':
define('BASE_URL', 'http://localhost/');
define('BASE_PATH', '/www/myproject/');
break;
}
Then maybe have a URL helper file.
url_helper.php
function site_url($relative) {
return BASE_URL . $relative;
}
function redirect($uri = '', $method = 'location', $http_response_code = 302) {
if ( ! preg_match('#^https?://#i', $uri)) {
$uri = site_url($uri);
}
switch($method) {
case 'refresh' : header("Refresh:0;url=".$uri);
break;
default : header("Location: ".$uri, TRUE, $http_response_code);
break;
}
exit;
}
And a load helper.
load_helper.php
function load_file($uri) {
require BASE_PATH . $uri;
}
function load_class($class) {
if ( ! class_exists($class))
load_file('class/' . $class);
}
These functions could be more robust to suit your needs. The advantage is you can have different configurations for Production/Development, various servers, or simply for specific environments. If you always use the site_url function to generate URLs around your site, you can easily change how your URLs are interpreted by making one change in a single file.
Maybe something like this could do the trick!
switch(dirname(__FILE__)) {
case '/www/myproject/inc/':
//DEFINE SOMETHING
break;
case '/www/myproject/':
//DEFINE SOMETHING
break;
}
As stated in the docs __DIR__
returns the directory of the file where it was used.
DIR - The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(FILE). This directory name does not have a trailing slash unless it is the root directory. (Added in PHP 5.3.0.)
To include a file in an outer directory you'll have to use ..
to "get out" of the inner directory.
require_once(__DIR__ . '../config.php');
On a side note, I would suggest you check out FIG's autoloading standards if you are using PHP's namespaces.
I know this answer is late, but you haven't accepted any yet, so I thought I'd throw in to the pot what I use for most of my applications.
First things first, from the file you call your config.php
from, you will always need to use a relative reference for it, ie require_once '../config.php';
from your example. Granted, you can 'gather' the full path to the config file from PHP commands, but why would you do that when you know its one directory up, and within it, you can then define
the base path for the entire project. For example, in your www/myproject/inc/usercontroller.php
file, the top would look like:
<?php
require_once '../config.php';
And then, to auto-get the full basepath of the project for use in other includes or the like, in your config, you'd have something like:
<?php
$basepath = dirname(__FILE__);
define('BASEPATH', $basepath);
//Or all in one line:
define('BASEPATH', dirname(__FILE__));
From there, just use BASEPATH
when you need the full path to the root of the project. ^^