Php 5.4 Include / require -- cannot get file path right - php

Suppose i have this file:
/Home/user/docs/somewhere/inHere.php
And in this php, i want to require this:
/Home/user/other/well/buried/place.php
I know the difference between an absolute and relative path, but cannot seem to figure out how php wants this to look, i keep getting 'file not found or does not exist'
I am on a hostgator shared web server, if that has any bearing on anything.

Include it using absolute paths.
Either:
include '/Home/user/other/well/buried/place.php';
or do it relative from where you are, but still absolute:
include __DIR__ . '/../../other/well/buried/place.php';
The magic constant __DIR__ contains the absolute path to the file it was written in.
If you just do a relative path include '../../and-so-on', the starting point will change if you're including that file in some other file that resides in some other location.

Firstly you can get the current folder using getcwd().
Next, you can use $path = '../../etc'; $realPath = realpath($path). It will return false if the path is wrong, and the concrete path without relative ../'s if it is indeed an actual path.
If you still can't get it, var_dump($path); and then copy the path and try to cd into it, you should diascover what you are doing wrong at that point.

From the file location (somewhere) you have to go upwards (to docs) and another time (to user), and then go inside "other", like this:
include ("../../other/well/buried/place.php");
There you go.

Related

include strange behaviour with relative path

In my php project I try to include another file. However, I find it very confusing how the include statement works.
e.g.
I include the file HelperFile.php in index.php. Both files are in the same directory.
This works: include 'HelperFile.php' but this doesn't include '/HelpferFile.php' & include './HelpferFile.php'
The warning I receive:
PHP Warning include(/HelperFile.php): failed to open stream
Out of curiosity I created a folder and moved my file HelperFile.php into it and nothing changed. Everytime I tried to use the relative path with ./, ../ or /I received a warning.
Can someone explain me what's going on. I'm still learning and can'f figure out what's happening right now.
PHP isn't so great with relative paths, it generally prefers absolute paths. The easiest way around this is to use the DIR magic constant which returns the current directory of the file you're currently in.
So, for instance, you can do include(__DIR__ . '/HelperFile.php'); which would be in the current directory.
However say you had a file in a folder up you can do
include(__DIR__ . '/../MyOtherFile.php');
PHP Doc says
If a path is defined — whether absolute (starting with a drive letter
or \ on Windows, or / on Unix/Linux systems) or relative to the
current directory (starting with . or ..) — the include_path will be
ignored altogether. For example, if a filename begins with ../, the
parser will look in the parent directory to find the requested file.
If you use . or .. will ignored for relative path Also use ../ for parent directory.

PHP include file as an absolute path - is this correct?

I have several instances of php includes on some of my pages (usual things like footer markup and headers etc) and Id rather use an absolute php path rather than the ../../ relative path I am using.
I thought this would work:
<?php include
include(dirname(__FILE__) . "/dir/script_name.php");
?>
my question is: is the /dir/script_name.php - the exact full path, and if so, what is the point of __FILE__ ?
The function dirname() removes the file name from the path and gives us the absolute path of the directory the file is in - right? So why bother with the function dirname() if I am already giving the full path - ?
Hope that makes sense
__FILE__ is the php magic variable which is the full path of the currently executing file (where it appears), dirname() removes the file name from it, thereby giving you the full path of the folder the current script is in.
It is really just a hack, as another magic variable __DIR__ (the directory of the currently executing script) was only added in 5.3 and therefore the dirname(__FILE__) was the easiest way to achieve the same thing in earlier versions.
The function dirname() removes the file name from the path and gives us the absolute path of the directory the file is in - right?
Yes, this is correct. The path you can use could be relative or the full system path.
So why bother with the function dirname() if I am already giving the full path - ?
If you are hard coding the full file system path then your application will become less portable; Your webroot directory would be different from mine. This is normally why you will see code with the path being generated like this.
I would personally look into the PHP autoloader as a much more flexible alternative to managing class includes.
It all depends on what you want. In the strictest sense, the path you're describing is "relative" to the file you're executing. For a true absolute path, just make sure the filename starts with a "/".
like so:
include "/path/to/file/script.php";

PHP include file by relative path

This absolute path successfully includes my file httpapi.inc.php:
require_once '/home/devel/wwwroot/nm/dev/http-api/http-api/src/httpapi.inc.php';
The calling file is:
Caller relative:
/devel/phi/dev/appcenter-head/appcenter/application/nm/index.php
Caller location:
/home/devel/wwwroot/phi/dev/appcenter-head/appcenter/application/nm
Now, how can I include that same file based on a relative path like:
/devel/nm/dev/http-api/http-api/index.php
I must use this path "as is", since it is a config option passed by the user.
require() and include() should operate relative to the configured include paths and the currently executing script. So, this should work:
require_once('src/httpapi.inc.php');
To be perfectly precise, though, the current script's working directly is actually designated as one of the include paths in the default configuration. It won't work if you've mucked with it.
Using a . in the include path allows for relative includes as it means
the current directory.
Regarding your latest edit, your paths are different enough that it's simpler to just use the full path or add /home/devel/wwwroot/nm/dev/http-api/http-api/ to your config and use require_once('src/httpapi.inc.php').
You might use the document root from the $_SERVER variable:
http://www.php.net/manual/en/reserved.variables.server.php
require_once $_SERVER['DOCUMENT_ROOT'] . '/nm/dev/http-api/http-api/src/httpapi.inc.php';
include "src/httpapi.inc.php";

Problem with require() when using a fully qualified URL

So, my code was using relative paths, but running into some problems with common files which could be include/required from different directory levels.
Absolute paths are more efficient anyway, right? So, I changed all include/require to absolute paths, using require_once('http://' . $_SERVER['HTTP_HOST'] . 'file_name.php');
$_SERVER['HTTP_HOST'] is correct, isn't it? It seemed so when I googled.
That required me to set 'allow_url_include=on` in php.ini and restart Apache.
So, now I have a situation that looks something like this (simplified example):
File2.php contains
<?php
function hello()
{
echo 'hello<br>';
}
?>
and if file1.php contains
<?php
require_once('file2.php');
hello();
?>
then I see the expected output "hello", but if I change that line to
require_once('http://' . $_SERVER['HTTP_HOST'] . '/file2.php');
Then I get "Fatal error: Call to undefined function hello() in C:\xampp\htdocs\file1.php"
(I guess that the reference to c:\xammp\httdos came from Xdebug, because PhpInfo shows HTTP_HOST localhost)
Anyway, that's a long post to say that I am missing some simple point and to ask what it is.
When you require a full URL, PHP makes a request to the server and gets back the output of the PHP script - this will not contain any actual PHP code (unless the script itself outputs PHP code).
Also, you aren't going to see any noticeable difference in performance between using relative and absolute paths, so don't worry too much about it. In fact, your path is not an absolute path but an absolute URI, and fetching a URI is actually going to be way slower than using local paths.
require_once expects a path on the server and not a URL. So for example you can't pass http://www.foo.com/test.php but you can do /var/www/foo/test.php. If you put http:// path then it will only include the output and not the php functions.
Absolute means relative to the file system. You're using url includes when you use http://..., but you're using normal includes when you use file2.php. To use real absolute paths use require_once('/xampp/htdocs/file2.php');.
When you require or include a file in PHP, the file is merged into the current script from the local filesystem unless the file path includes a schema such as HTTP, then it will be included by one of the fopen wrappers. See http://www.php.net/manual/en/function.include.php
PHP determines the full path to the file based on certain factors.
An absolute path (one beginning with a DIRECTORY_SEPARATOR (eg /) or drive letter identified (eg C:\) for Windows servers) is the quickest as there is no translation to do. The file is simply merged in from the given location.
A relative path however is much more complex than most imagine.
PHP will search for the relative path in the include_path stack (FIFO). This is a PATH_SEPARATOR (;) delimited string containing one or more "base" paths.
An example include path is
/usr/share/pear;.
This contains two paths, /usr/share/pear and ., the current working directory (CWD).
You will receive the best performance in your application if you specifically set your include path and remove anything not relevant. For example, say all your "includable" files reside in /home/me/www/appname/includes, your best bet is to set this in your bootstrap / common script, eg
set_include_path('/home/me/www/appname/includes');
Now any relative include call will only fetch from this location.
If you need to set multiple paths, I find something like this works well
set_include_path(implode(PATH_SEPARATOR, array(
'/include/path/one',
'/include/path/two'
)));
and if you want to ammend the server include path, I'd advise to add it in the same way but place it at the bottom of the stack, eg
set_include_path(implode(PATH_SEPARATOR, array(
'/include/path/one',
'/include/path/two',
get_include_path()
)));
IMHO, one of the best things you can do is remove the CWD from the include path as it tends to be one of the biggest sources of "include path hell". If you do need to include a file relative to the current one, use
require_once realpath(dirname(__FILE__)) . '/relative/path/to/file.php';
You can use file_get_contents function
file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/file2.php');
But it is mainly useful for connecting to an external domain

How do I set an absolute include path in PHP?

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".

Categories