My PHP application has different config files with their different settings and their different paths. But all of them need to access to just one database connection file. I would like to avoid mention its path separately on them with many ../ and ../../. How can I write a same code and use it in all of them?
Imagine that my PHP application has this hierarchy for its config files:
root
root/config/db.php (This file is what I want to mention from all config files.)
root/admin/config/conf.php
root/users/conf.php
Actually what I need is something that detect the root path of my project and create a same directory path generally.
Use $_SERVER['DOCUMENT_ROOT'] and then path to your file.
Use PHP's class autoloading, the catch being you then need to wrap up your config information in a class, but it works.
require_once("../../config/db.php");
Include this file into "conf.php" file
Set the include_path directive as either root/ or root/config/ either by editing your php.ini file or by calling set_include_path on every page. This way, you can just include/require "db.php" on each page.
Related
I have a php file outside my webroot in which I want to include a file that is inside the webroot.
folder outside webroot
- > php file in which I want to include
webroot
- > file to include
So I have to go one directory up, but this doesnt work:
include('../webroot/file-to-include.php');
Include full path doesn't work either:
include('home/xx/xx/domains/mydomain/webroot/file-to-include.php');
How can I accomplish this?
Full path should be:
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Or you should set the path like:
include(__DIR__ . '/../webroot/file-to-include.php'); // php version >= 5.3
include(dirname(__FILE__) . '/../webroot/file-to-include.php'); // php version < 5.3
Have this in a common file, shared by all your php sources outside the webroot:
<?php
define('PATH_TO_WEBROOT', '/home/xx/xx/domains/mydomain/webroot');
And then use the following to include files.
<?php
include (PATH_TO_WEBROOT.'/file-to-include.php');
If the location of your webroot changes, you will only have to change that once in your code base.
You can configure php to automatically prepend a given file to all your scripts, by setting the auto_prepend_file directive. That file could for instance contain the PATH_TO_WEBROOT constant, or require_once the file which contains it. This setting can be done on a per domain or per host basis (see the ini sections documentation).
Also, consider using the autoload feature if you are using classes extensively.
Try prepending a trailing slash to your full path, so it looks like
include('/home/xx/xx/domains/mydomain/webroot/file-to-include.php');
Otherwise, it will be interpreted as a relative path.
You could also try to change the dir into the webroot and see if this works - for debuggign purposes:
chdir("/home/xx/xx/domains/mydomain/webroot");
include "your_file.php";
I put the secured data in the file named conn.txt,
and then I used the following PHP command:
$DbInfoFile = "../conn.txt";
Fast forward to the current day (2021), an alternative method is to simply add the PHP include_path directive into your php.ini (or user.ini) to point to the includes folder, wherever it is (inside or outside the public root). This method blends the ease of changing one line of code in your project without touching the the PHP code at all. I have no idea if this works on a Windows box since I'm on CentOS.
Example: include_path = ".:/home/{acct-name}/{include-path}" (this would be one level up from public_html or whatever your public folder is called)
This blended approach allows you to simply invoke include 'file-to-include.php'; in your PHP code without going through the whole hassle of defining the root, while retaining the flexibility of changing the includes file by modifying only one line of code sitewide.
By the way, you can have multiple include locations. In that case, you can separate the two locations with a colon such as include_path = ".:/home/{acct-name}/{include-path-1}:/home/{acct-name}/{include-path-2}".
This should work
$_SERVER['DOCUMENT_ROOT']/home/xx/xx/domains/mydomain/webroot/file-to-include.php
And make sure you have access to that level.
this is how my file structure is. [..] are folders
[public]
[libs]
[crontab]
[logs]
[sessions]
[tmp]
config.php
the domain is set to the public folder as its root. everything else including the config.php file is outside the root. the config contains db connection information and other necessary settings.
every page in the public folder i have to put the entire path so include the config file. problem is when i move everything from my local machine to the public server i have to go through every page and change the path included for the config file. is there a better way? maybe settings a path in php.ini or something like that?
thanks
In that specific case you can use:
include("$_SERVER[DOCUMENT_ROOT]/../config.php");
# Note: special exception array syntax within double quotes.
Which resolves to the public directory first, but moves one level back ../ to reach the config file outside of the docroot.
But you could also use SetEnv in your .htaccess to define another $_SERVER environment variable for the occasion.
A technique that I frequently use to include files relative to a particular location in your webroot structures is to use an include/require like this:
require_once(dirname(__FILE__) . '/path/to/include.php');
This way, codebase migrations don't need to change any hard-links or constants so long as the files remain relative to each other in the same way.
You could just use constant for your path and change it once, and define that constant on every path - included file
You can also take a look at include path
http://php.net/manual/en/function.set-include-path.php
See set_include_path() and the docs for the include_path ini setting.
I'm having problems with my include files. I don't seem to be able to figure out how to construct my URLs when I use require_once('somefile.php'). If I try to use an include file in more than one place where the directory structures are different, I get an error that the include file cannot be found.
In asp.net, to get my application root path, I can use ~/directory/file.aspx. The tild forward slash always knows that I am referencing from my website root and find the file no matter where the request comes from within my website. It always refers back to the root and looks for the file from there.
QUESTION: How can I get the root path of my site? How can I do this so I can reuse my include files from anywhere within my site? Do I have to use absolute paths in my URLs?
Thank you!
There is $_SERVER['DOCUMENT_ROOT'] that should have the root path to your web server.
Edit: If you look at most major php programs. When using the installer, you usually enter in the full path to the the application folder. The installer will just put that in a config file that is included in the entire application. One option is to use an auto prepend file to set the variable. another option is to just include_once() the config file on every page you need it. Last option I would suggest is to write you application using bootstrapping which is where you funnel all requests through one file (usually with url_rewrite). This allows you to easily set/include config variables in one spot and have them be available throughout all the scripts.
I usually store config.php file in ROOT directory, and in config.php I write:
define('ROOT_DIR', __DIR__);
And then just use ROOT_DIR constant in all other scripts.
Using $_SERVER['DOCUMENT_ROOT'] is not very good because:
It's not always matching ROOT_DIR
This variable is not available in CGI mode (e.x. if you run your scripts by CRON)
It's nice to be able to use the same code at the top of every script and know that your page will load properly, even if you are in a subdirectory. I use this, which relies on you knowing what your root directory is called (typically, 'htdocs' or 'public_html':
defined('SITEROOT') or define('SITEROOT', substr($_SERVER['DOCUMENT_ROOT'], 0, strrpos($_SERVER['DOCUMENT_ROOT'], 'public_html')) . 'public_html');
With SITEROOT defined consistently, you can then access a config file and/or page components without adapting paths on a script-by-script basis e.g. to a config file stored outside your root folder:
require_once SITEROOT . "/../config.php";
You should use the built in magic constants to find files. __FILE__ and __DIR__. If you are on PHP < 5.3 you should use dirname(__FILE__)
E.g.
require_once __DIR__.'/../../include_me.php';
$_SERVER['DOCUMENT_ROOT'] is not always guaranteed to return what you would expect.
Define it in a config file somewhere.
Assuming you're using an MVC style where everything gets routed through a single index.php then
realpath('.');
Will show you the path to the current working directory (i.e where index.php is)
So then you can define this as
define('PROJECT_ROOT', realpath('.'));
If it's not MVC and you need it to work for files in subfolders then you can just hard code it in a config file
define('PROJECT_ROOT', 'C:/wamp/www/mysite');
Then when including something you can do;
include PROJECT_ROOT . '/path/to/include.php';
You could alternativly set the base directory in your .htaccess file
SetEnv BASE_PATH C:/wamp/www/mysite/
Then in PHP you can reference it with $_SERVER['BASE_PATH']
Try this:
$_SERVER['DOCUMENT_ROOT']
I am developing a web application. contents are:
root dir (/var/www/)
config.php
index.php
details.php
admin dir (/var/www/admin)
admin.php
I have included config.php file into index.php, details.php in root directory using require_once('config.php') as this file contains database passwords, styles, images directory paths..
how can i include that config files in my admin/admin.php file so that one config file can be used in anywhere(even in subdirectories) of my web application. Will it make any difference for the value of define('APP_BASE_PATH', dirname(__FILE__)); when same config file is used by all files in the web application.
if i am wrong somewhere then please get me right.
If your server properly configured, just
include $_SERVER['DOCUMENT_ROOT']."/config.php";
anywhere
You have also 2 other possible ways.
a Front controller setup, where ALL user requests going into one file. And ths one going to include all others from their subdirectories. Personally I don't like it cause this front file become a mess. Though it's widely used.
I decided not to mention it because noone would use a hardcoded full path anyway.
Update after clarification in comments: You are looking for a way to include a central configuration file from anywhere in your project's folder structure.
#Col. Shrapnel shows one way, DOCUMENT_ROOT. It's the only way to use an "absolute" path from a nested folder structure. It has the limitation I describe above, but it's fine otherwise.
If you want maximum portability (i.e. the possibility to run the app with e.g. www.example.com/myapp/version_1 as its root directory), you would have to use relative references from within your folder structure to "climb down" to the config file, e.g. ../../config.php that will work reliably too, although be a bit cumbersome e.g. if you move a script to a different folder and you have to update the relative path.
you can use the same config file every time... using "/" will take you back to the root directory... so in admin/admin.php use this:
require_once("/config.php");
you can use "../" to take you up one directory eg:
require_once("../config.php");
was this what you were looking for?
In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:
/images/some_image.jpg
I can put that path in any file in any subdirectory, and it will point to the right image.
With PHP, I tried something similar:
include("/includes/header.php");
...but that doesn't work.
I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:
Using a . in the include path allows for relative includes as it means the current directory.
Relative includes are exactly what I don't want.
How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)
Clarification
My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)
Update
I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.
One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.
Anyway, problem solved! :)
What I do is put a config.php file in my root directory. This file is included by all PHP files in my project. In that config.php file, I then do the following;
define( 'ROOT_DIR', dirname(__FILE__) );
Then in all files, I know what the root of my project is and can do stuff like this
require_once( ROOT_DIR.'/include/functions.php' );
Sorry, no bonus points for getting outside of the public directory ;) This also has the unfortunate side affect that you still need a relative path for finding config.php, but it makes the rest of your includes much easier.
One strategy
I don't know if this is the best way, but it has worked for me.
$root = $_SERVER['DOCUMENT_ROOT'];
include($root."/path/to/file.php");
The include_path setting works like $PATH in unix (there is a similar setting in Windows too).It contains multiple directory names, seperated by colons (:). When you include or require a file, these directories are searched in order, until a match is found or all directories are searched.
So, to make sure that your application always includes from your path if the file exists there, simply put your include dir first in the list of directories.
ini_set("include_path", "/your_include_path:".ini_get("include_path"));
This way, your include directory is searched first, and then the original search path (by default the current directory, and then PEAR). If you have no problem modifying include_path, then this is the solution for you.
There is nothing in include/require that prohibits you from using absolute an path.
so your example
include('/includes/header.php');
should work just fine. Assuming the path and file are corect and have the correct permissions set.
(and thereby allow you to include whatever file you like, in- or outside your document root)
This behaviour is however considered to be a possible security risk. Therefore, the system administrator can set the open_basedir directive.
This directive configures where you can include/require your files from and it might just be your problem.
Some control panels (plesk for example) set this directive to be the same as the document root by default.
as for the '.' syntax:
/home/username/public_html <- absolute path
public_html <- relative path
./public_html <- same as the path above
../username/public_html <- another relative path
However, I usually use a slightly different option:
require_once(__DIR__ . '/Factories/ViewFactory.php');
With this edition, you specify an absolute path, relative to the file that contains the require_once() statement.
Another option is to create a file in the $_SERVER['DOCUMENT_ROOT'] directory with the definition of your absolute path.
For example, if your $_SERVER['DOCUMENT_ROOT'] directory is
C:\wamp\www\
create a file (i.e. my_paths.php) containing this
<?php if(!defined('MY_ABS_PATH')) define('MY_ABS_PATH',$_SERVER['DOCUMENT_ROOT'].'MyProyect/')
Now you only need to include in every file inside your MyProyect folder this file (my_paths.php), so you can user MY_ABS_PATH as an absolute path for MyProject.
Not directly answering your question but something to remember:
When using includes with allow_url_include on in your ini beware that, when accessing sessions from included files, if from a script you include one file using an absolute file reference and then include a second file from on your local server using a url file reference that they have different variable scope and the same session will not be seen from both included files. The original session won't be seen from the url included file.
from: http://us2.php.net/manual/en/function.include.php#84052
hey all...i had a similar problem with my cms system.
i needed a hard path for some security aspects.
think the best way is like rob wrote. for quick an dirty coding
think this works also..:-)
<?php
$path = getcwd();
$myfile = "/test.inc.php";
/*
getcwd () points to:
/usr/srv/apache/htdocs/myworkingdir (as example)
echo ($path.$myfile);
would return...
/usr/srv/apache/htdocs/myworkingdir/test.inc.php
access outside your working directory is not allowed.
*/
includ_once ($path.$myfile);
//some code
?>
nice day
strtok
I follow Wordpress's example on this one. I go and define a root path, normally the document root, and then go define a bunch of other path's along with that (one for each of my class dirs. IE: database, users, html, etc). Often I will define the root path manually instead of relying on a server variable.
Example
if($_SERVER['SERVERNAME'] == "localhost")
{
define("ABS_PATH", "/path/to/upper/most/directory"); // Manual
}
else
{
define("ABS_PATH, dirname(__FILE__));
// This defines the path as the directory of the containing file, normally a config.php
}
// define other paths...
include(ABS_PATH."/mystuff.php");
Thanks - this is one of 2 links that com up if you google for php apache windows absolute path.
As a newbie to intermed PHP developer I didnt understand why absolute paths on apache windopws systems would be c:\xampp\htdocs (apache document root - XAMPP default) instead of /
thus if in http//localhost/myapp/subfolder1/subfolder2/myfile.php I wanted to include a file from http//localhost/myapp
I would need to specify it as:
include("c:\xampp\htdocs\myapp\includeme.php")
or
include("../../includeme.php")
AND NOT
include("/myapp/includeme.php")
I've come up with a single line of code to set at top of my every php script as to compensate:
<?php if(!$root) for($i=count(explode("/",$_SERVER["PHP_SELF"]));$i>2;$i--) $root .= "../"; ?>
By this building $root to bee "../" steps up in hierarchy from wherever the file is placed.
Whenever I want to include with an absolut path the line will be:
<?php include($root."some/include/directory/file.php"); ?>
I don't really like it, seems as an awkward way to solve it, but it seem to work whatever system php runs on and wherever the file is placed, making it system independent.
To reach files outside the web directory add some more ../ after $root, e.g. $root."../external/file.txt".