include and include_once issue in PHP - php

I currently working on a PHP project. I copy the project file to my local box. It runs fine except one thing.
Here is the folder hierarchy:
root/index.php
root/event/admin/list.php
root/event/admin/functions.php
In the index.php, there is a line:
<?php include ("event/admin/list.php"); ?>
which should include the list.php
However in the list.php, there is a line:
<?php include_once "event/admin/functions.php";?>
Since the list.php is not in the root directory, event/admin/functions.php did not get call and my local index.php fail to load this part.
But the production is working fine.
Does anyone know what happened? Is that a way to setup include/include_once always use ROOT directory without using something like $_SERVER["DOCUMENT_ROOT"]? Thanks a lot.

It is a good idea to use $_SERVER['DOCUMENT_ROOT'], in my opinion. You can do so like this:
include_once($_SERVER['DOCUMENT_ROOT'] . "/path/to/file.php");
However, try replacing he code in list.php with this:
<?php include_once "../../event/admin/functions.php";?>
This is a known issue relating to relative paths. Thus, DOCUMENT_ROOT is preferable. Alternatively, you can edit include_path.

Set the include path to whatever is useful for your probject.

This is a common issue related to relative paths. You can either include your files from an absolute path, or modify your include_path in php.ini to use your doc root, and specify files relative to there.

Compare the include path configuration between the two machines.

Related

PHP - Going back directories

I've encountered something when trying to include/require a php script that's 2 directories back. It's not really a problem as I figured out a work around, however I'd love an explanation for what's happening.
Here's the file structure:
appCode
db.php (File I'm trying to include)
studentManagement
index.php
dep
getData.php (File I'm trying to include db.php into)
I want to include appCode/db.php in studentManagement/dep/getData.php.
getdata.php is executed with ajax from index.php
When I use:
require_once("../../appCode/db.php");
It doesn't work.
The only way it works is it I change directory first:
chdir("../");
require_once("../appCode/db.php");
Why won't the first method work? I've also tried using include instead of require but it's the same. I'm testing it on mamp 3.0.4.
Any help appreciated!!
that is because when you require(),include() and their variants it's always relative to the initial php file called (in your case index.php)
in fact chdir has nothing to do with it, and this:
require_once("../appCode/db.php");
is the right way to call it.
always place your mental self (!) as if you were index.php when you require files and work with directories. your "active directory" is the one where index.php is placed. you can always verify this current working directory with getcwd() http://php.net/manual/en/function.getcwd.php
If you know your entire directory all the way from root you can use:
http://php.net/manual/en/function.set-include-path.php
Now instead of using relative paths you can always include or require files starting at your include path.
You could put this in getData.php:
set_include_path ('/homepages/www/2/yourworkingpath');//Use your own directory
require_once 'appCode/db.php';
You could also do the same thing in your other files if you need to include and it will always use your include path so you don't have to keep figuring out which directory to change to. Hopefully this helps a bit.

Why would I use dirname(__FILE__) in an include or include_once statement?

I have seen this:
<?php
include( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'my_file.php');
?>
Why would I ever need to do this? Why would I go to the trouble of getting the dirname and then concatenating that with a directory separator, and a new filename?
Is the code above not equivalent to this:
<?php
include( 'my_file.php' );
?>
??
The PHP doc says,
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing. The include() construct will emit a warning if it cannot find a file; this is different behavior from require(), which will emit a fatal error.
Let's say I have a (fake) directory structure like:
.../root/
/app
bootstrap.php
/scripts
something/
somescript.php
/public
index.php
Now assume that bootstrap.php has some code included for setting up database connections or some other kind of boostrapping stuff.
Assume you want to include a file in boostrap.php's folder called init.php. Now, to avoid scanning the entire include path with include 'init.php', you could use include './init.php'.
There's a problem though. That ./ will be relative to the script that included bootstrap.php, not bootstrap.php. (Technically speaking, it will be relative to the working directory.)
dirname(__FILE__) allows you to get an absolute path (and thus avoid an include path search) without relying on the working directory being the directory in which bootstrap.php resides.
(Note: since PHP 5.3, you can use __DIR__ in place of dirname(__FILE__).)
Now, why not just use include 'init.php';?
As odd as it is at first though, . is not guaranteed to be in the include path. Sometimes to avoid useless stat()'s people remove it from the include path when they are rarely include files in the same directory (why search the current directory when you know includes are never going to be there?).
Note: About half of this answer is address in a rather old post: What's better of require(dirname(__FILE__).'/'.'myParent.php') than just require('myParent.php')?
I might have even a simpler explanation to this question compared to the accepted answer so I'm going to give it a go: Assume this is the structure of the files and directories of a project:
Project root directory:
file1.php
file3.php
dir1/
file2.php
(dir1 is a directory and file2.php is inside it)
And this is the content of each of the three files above:
//file1.php:
<?php include "dir1/file2.php"
//file2.php:
<?php include "../file3.php"
//file3.php:
<?php echo "Hello, Test!";
Now run file1.php and try to guess what should happen. You might expect to see "Hello, Test!", however, it won't be shown! What you'll get instead will be an error indicating that the file you have requested(file3.php) does not exist!
The reason is that, inside file1.php when you include file2.php, the content of it is getting copied and then pasted back directly into file1.php which is inside the root directory, thus this part "../file3.php" runs from the root directory and thus goes one directory up the root! (and obviously it won't find the file3.php).
Now, what should we do ?!
Relative paths of course have the problem above, so we have to use absolute paths. However, absolute paths have also one problem. If you (for example) copy the root folder (containing your whole project) and paste it in anywhere else on your computer, the paths will be invalid from that point on! And that'll be a REAL MESS!
So we kind of need paths that are both absolute and dynamic(Each file dynamically finds the absolute path of itself wherever we place it)!
The way we do that is by getting help from PHP, and dirname() is the function to go for, which gives the absolute path to the directory in which a file exists in. And each file name could also be easily accessed using the __FILE__ constant. So dirname(__FILE__) would easily give you the absolute (while dynamic!) path to the file we're typing in the above code. Now move your whole project to a new place, or even a new system, and tada! it works!
So now if we turn the project above to this:
//file1.php:
<?php include(dirname(__FILE__)."/dir1/file2.php");
//file2.php:
<?php include(dirname(__FILE__)."/../file3.php");
//file3.php:
<?php echo "Hello, Test!";
if you run it, you'll see the almighty Hello, Test!! (hopefully, if you've not done anything else wrong).
It's also worth mentioning that from PHP5, a nicer way(with regards to readability and preventing eye boilage!) has been provided by PHP as well which is the constant __DIR__ which does exactly the same thing as dirname(__FILE__)!
Hope that helps.
I used this below if this is what you are thinking. It it worked well for me.
<?php
include $_SERVER['DOCUMENT_ROOT']."/head_lib.php";
?>
What I was trying to do was pulla file called /head_lib.php from the root folder. It would not pull anything to build the webpage. The header, footer and other key features in sub directories would never show up. Until I did above it worked like a champ.
If you want code is running on multiple servers with different environments,then we have need
to use dirname(FILE) in an include or include_once statement.
reason is follows.
1. Do not give absolute path to include files on your server.
2. Dynamically calculate the full path like absolute path.
Use a combination of dirname(FILE) and subsequent calls to itself until you reach to the home of your '/myfile.php'.
Then attach this variable that contains the path to your included files.

PHP Relative paths like ASP

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

How to include file from another directory

In the root (www) I have two folders.
In the first folder, "folder1", I put a file called register.php.
In the next folder, "folder2", I put files called header.php and footer.php.
I need to include the header and footer files from folder2 in the register.php file.
How can i do this? I tried to use this include ../folder2/header.php
..but it does not work
On some configurations, adding ./ (current dir) does the trick like this:
include './../folder2/header.php';
Alternatively, you can specify in terms of document root:
include $_SERVER['DOCUMENT_ROOT'] . 'folder2/header.php';
<?php include( $_SERVER['DOCUMENT_ROOT'] . 'folder2/header.php' ); ?>
include $_SERVER['DOCUMENT_ROOT'] . '/folder2/header.php';
would work from any directory of the site
it is called absolute path and it's the only reliable way to address a file
However, in real it should be something like
include $_SERVER['DOCUMENT_ROOT'] . '/cfg.php';
// some code
include $TPL_HEADER;
using a variable, previously defined in cfg.php
However, it may fail too. Because you can be just wrong about these paths
And here goes your main problem:
but it does not work
There is no such thing as "it does not work"
There is always a comprehensive error message that tells you what exactly doesn't work and what it does instead. You didn't read it yourself, and you didn't post it here to let us show you a correct path out of these error messages.
include files should generally be kept outside of the server root.
lets say your setup is;
www/website1
and
www/includes
Then you php.ini file, or .htaccess file should stipulate that
include_path=www/includes
then from any of your files, in any directory, no matter how far down the trees they go you simply do:
include 'myfile.php';
where myfile.php is at www/includes/myfile.php
Then you can stop worrying about these issues
include dirname(__FILE__).'/../folder2/header.php';
Try This it is work in my case
<?php require_once __DIR__."/../filename.php";?>
As the PHP manual states here $_SERVER['DOCUMENT_ROOT'] is "The document root directory under which the current script is executing, as defined in the server's configuration file." For this example, $_SERVER['DOCUMENT_ROOT'] will work just fine but. . . By using the new "magic constants" provided in >= PHP 5.3, we can make this code a little safer.
Put your includes in a subfolder, and use the magic constant DIR to make a reference to the included files. DIR returns the directory of the currently executing php file. By using this, you can move your folder containing all your includes anywhere you like in your directory structure, and not need to worry if your includes will still work.

PHP include file

i have two files:(localhost/template/)
index.php
template.php
each time when i create an article(an article system is what i'm trying to do),i create a folder and then i copy the index.php in that folder. I want to include template php in index.php but as a static url('cause the articles will be like a folder-subfolder/subfolder/.. structure )
i tried: include('localhost/template/template.php') with no result. how should i include it? thanks
The include method works on the file system path, not the "url path". Solution is to either
Give it an absolute path.
-- include('/some/path/to/template.php');
Change the relative path so it is correct after each copy you create.
-- include('../../template.php');
Change the include path of PHP so that the file is in, well, the include path.
-- Can be done either in the php.ini file, in the .htaccess file or with the set_include_path function. (Depending on how much you want to set it for, and what you have permission for)
You could include it relative to the current directory, like so:
require_once(dirname(__FILE__) . '/template.php');
dirname(FILE) will translate to the directory of the current script (index.php) and the line above will append '/template.php' resulting in the full path to the template.php side-by-side to the index.php file.
I find it best to include files this way vs without a full path to avoid issues with the PHP search path, for example. It's very explicit this way.
UPDATE: I misunderstood the original question. It sounds like template.php isn't copied, only index.php is. So you'll have something that could be like:
template/template.php
template/index.php (just a template)
foo/bar/index.php
foo/bar2/index.php
Since people can hit the foo/bar/index.php for example without funneling through a central script, you'll have to somehow find the template no matter where you are.
You can do this by setting the PHP include_path, for example through a .htaccess on a Apache server:
php_value include_path ".:/home/<snip>/template"
Then in each index.php you can include template.php and it'll search the current directory first, then try your template directory.
You could also compute the relative path when copying the script and put an include in there with the proper number of '..' to get out (e.g. '../../template/template.php'). It's kinda fragile, though.
You don't want the "localhost" in there. Includes work using the actual path on your server.
So you can either use relative ones such as posted above, or absolute in terms of server so this could be "/opt/www/" on linux or "c:\Program Files\Apache\htdocs" on windows. This will be different from system to system so to find out yours use the dirname(__FILE__) technique shown by wojo.
If you're trying to include the file as an url, you'll need to start it with http:// and have allow_url_include set to true in PHP settings. This is highly discouraged as it opens doors for security breaches.
Instead, you should either add localhost/template to your include path or use relative urls like include('../template.php').
The path looks wrong, you should include it with a path relative to where the calling file is, e.g. include('template/template.php'); or include('../template/template.php');

Categories