in my config.php where i have all constants i set the PATH to a absolute path.
but this means that when i move my application folder i have to change this path.
i wondered if its better to set a relative path, in that way whenever i move my application between production and development folder, i dont have to change it.
how do you guys do when you move between folders?
The best way I've found is to do the following:
define("PATH", realpath(dirname(__FILE__)));
That gives you the directory of the current file. If you do this in your settings/bootstrap/init file, you'll have it available to your application, and it will work for any file system.
__FILE__ is your friend.
define('BASE_PATH', dirname(realpath(__FILE__)));
This will make your scripts more portable.
Include a file like this
include BASE_PATH . 'includes/header.php';
IMO, absolute paths are bad news. Even if you don't plan to move, your hosting provider could move you, like DreamHost recently did to me. I was fine....
But there are 14 references to "path" on their wiki:
http://wiki.dreamhost.com/Server_Moves
I do three things to solve this:
The first is to use paths relative to the current file and include things using dirname(__FILE__).
The second is to use a loader include that all the pages load. This file has one responsibility: to find the include directory, usually via a relative call. So long as this relative relationship stays, it doesn't need changing.
I also like to support custom settings that belong to the installation rather than the codebase. This is done by an include mechanism and overrides a few settings that will be specific for the server the code is on.
Related
I have been trying to research what is better to use in order to include repetitive parts of the website - php include function or library(provided in Dreamweaver).
Or maybe there are other - better ways to achieve the same result?
At the moment I use php include and absolute paths. I downloaded the website from the server but it seems that the paths that work on the server don't work on my localhost.
What would be the correct and the best way to write paths in order to make them work on both servers without having to re-write the code?
Thanks
You can call at the start of your script the set_include_path() command and specify relative paths to your libraries
http://www.php.net/set_include_path
Since dream weaver uses library, that's probably wrong ;)
If you want to be sure the code is only included once you might use require_once instead.
Try relative paths instead of absolute
Also an easy way to solve this problem is to define a constant from within the root, normally within your index.php file.
/**Path Environment**/
$root=pathinfo($_SERVER['SCRIPT_FILENAME']);
define ('BASE_FOLDER', basename($root['dirname']));
define ('SITE_ROOT', realpath(dirname(__FILE__)));
define ('SITE_URL', 'http://'.$_SERVER['HTTP_HOST'].'/'.BASE_FOLDER);
Then you can use, SITE_URL and SITE_ROOT throughout your script knowing its the correct path to your web root.
So your old includes look like:
include('/srv/www/somesite.com/public_html/somefile.php');
and your new includes will look like include(SITE_ROOT.'/somefile.php'); then when developing on windows the path will change accordingly.
Put
include_path = ".:/your/absolute/path"
in your php.ini, both Server environment and localhost.
Then you can access the include path file at anywhere of the codes.
This works
<?php include("inc/c.php")?>
But in a folder past this, this does not work
<?php include("../inc/c.php")?>
I have to do
<?php include("/var/web/public_html/etc/inc/c.php")?>
I know in ASP you can enable virtual paths and directories. Is this the same with PHP?
If you're including a file from a folder, all includes are relative to the includer's file.
Therefore, the same code should work for the file in the sub-folder:
<?php include("inc/c.php")?>
You can use realpath(dirname(__FILE__)) to include files relatively to current file:
include(realpath(dirname(__FILE__).'/../inc/c.php'));
You can add directories to PHP's include_path directory. When you specify a relative file name, PHP will look for that file relative to all directories specified in the include_path.
Take a look at http://php.net/manual/en/function.set-include-path.php#example-488.
use
dirname(__file__)
it will return you path of current directory.
But in a folder past this, this does not work
Nope, it does work.
I know in ASP you can enable virtual paths and directories. Is this the same with PHP?
Yes. But whole virtual path thing has nothing to do with your case.
This is not PHP problem. This is developer's problem who is using wrong path.
To make your code fool-proof, always use absolute paths. Build paths not from current location but from the site root. So, it will be all the same in the ANY page on your site.
Most general way would be
include $_SERVER['DOCUMENT_ROOT']."/etc/inc/c.php";
I thought I would ask in case I could do it a better way.
On my local (WAMP) I have all my website in the www folder. ( C:\wamp\www )
Now currently I do this when i include a file:
require_once("".$_SERVER['DOCUMENT_ROOT']."/lib/config.php");
When I am working on local and upload site to a webhost i want to ensure the paths don't breakI
Could someone please tell me if I should be doing it this way?
I want to ensure maximum compatibility; meaning that paths won't break if I, for example, move site from local to whatever web host I decided to use or if I, for example, move from one host to another.
Maybe there is a more bullet proof way of doing it?
The problem with using $_SERVER['DOCUMENT_ROOT'] is that it will break if you move your PHP scripts up or down a directory level. Instead use this:
require_once(dirname(__FILE__) . "/lib/config.php");
__FILE__ is the absolute path of the script. dirname() removes the last path component (the script filename) so you can append other path components to it, like /lib/config.php or /../../lib/config.php or whatever. This will work everywhere.
PHP 5.3 introduced a shorthand for dirname(__FILE__), called __DIR__, but this doesn't work in <5.3.
You should see Include path. For that set_include_path is useful.
What I usually do, is make 1 config file (which might include others) with a few very basic constants:
define('PROJECT_ROOT', dirname(dirname(__FILE__))); // or dirname(__DIR__) for PHP 5.3
define('PROJECT_WEB', $_SERVER['DOCUMENT_ROOT']);
// etc
Al my other files/includes will be based on those very simple constants. I will never need relative paths and never the include_path, because both PROJECT_ROOT and PROJECT_WEB are 'real'/absolute.
Other useful (?) constants would be PROJECT_LOGIC and/or PROJECT_CONTROLLERS and/or PROJECT_3RD_PARTY etc.
That works fine for including the config file (although i would get rid of the beginning quotes)
require_once( $_SERVER['DOCUMENT_ROOT'] . "/lib/config.php" );
This is really the only way to do it if you are including the config file from a bunch of different directories.
On bigger project id say that "most" developers have a front controller that all scripts are loaded from. This front controller loads the config file and since its the same file always including the config file there's no need for $_SERVER['DOCUMENT_ROOT'].
I'm doing a little home computing project in PHP and am creating references like this...
Beer
This seems to pick up the right file. When I do includes, I seem to need a pathname.
include_once ("/var/www/common.php");
I'm sure this can't be right. Perhaps you could tell me what is the best practice for these things so that I can create scripts that aren't tied to a particular pathname (or operating system, come to that) and so that the file selected in the first example is known/can be controlled? Perhaps some settings in php.ini or apache?
Thank you.
You may use relative paths in PHP, too:
include_once './common.php';
This path now is relative to the script, which was intitially called.
If you leave out the dot
include_once 'common.php';
PHP will check all the paths in you include_path and if it doesn't find a file called common.php there, it will try to include common.php relative to the current file.
Many people have the practice of definining a constant like ROOT in the index.php which is used everywere else:
const ROOT = __DIR__; // as of PHP 5.3
define('ROOT', dirname(__FILE__)); // if you don't have PHP 5.3
Actually, you need an absolute path for both.
for the web resources it should start from the web root - /
for the files you need a point where virtual path meets a filesystem one.
$_SERVER['DOCUMENT_ROOT'] is for that purpose.
so
Beer
and
include_once ($_SERVER['DOCUMENT_ROOT']."/common.php");
will work as desired
You can:
Use relative pathnames. The paths should be relative to the directory where the script that is initially executed (unless the directory has been changed explicitly by the script).
Use $_SERVER['DOCUMENT_ROOT'].
The php ini file setting
include_path = var/www/includes
Means that you just forget all that crap about relative and absolute paths.
It matters not a wit where you call include/require.
Even in say:
/var/www/html/example.com/very/long/way/down/index.php
can contain the line;
include 'settings.php' ;
and if settings.php is in /var/www/includes/ then it will be included.
You can override the ini setting in a various places in apache too, even in .htaccess
This of course ties your application to your server settings, which some find unacceptable, but if you are not distributing your stuff, then read up on ini_get and ini_set too.
You can then go on and create natural directories in your include folder, such as /database and keep database settings in there too.
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".