Behaviour and correct use of the PHP include statement - php

I have the following directories and files:
└── project
├── index.php
└── lib
├── file1.php
└── file2.php
<?php
//index.php
include 'lib/file1.php';
<?php
//file1.php
include 'lib/file2.php';
<?php
//file2.php
echo 'this is from an echo statement in file2.php';
This does work when I try it in the browser as I expected. In particular I think the include statement in file1.php makes sense because it uses a path to file2.php relative to the location of index.php which includes file1.php and so is the location that file1.php's code will be executed.
However, I was surprised that if I change the include statement in file1.php to:
include 'file2.php';
it still works.
I would like to understand why both include statements work and get an idea of which of the two is the more correct.

From the documentation (emphasis mine):
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.
file1.php's own directory is lib, and it can find file2.php there.

According to the include documentation
Files are included based on the file path given or, if none is given, the include_path specified
The PHP parser would also look at file1's directory for file2 even if it was included from index's directory.
In file1.php the correct way to include it would be
include 'file2.php';
Because it would allow you to include file1.php from anywhere, not just 'project' directory:
include 'lib/file2.php';
Would not work if you decided to create another directory and include file1.php there (../file1.php)

Related

How can i get the file url and file path inside the code PHP [duplicate]

I want to use __dir__.
However, I can't find any good tutorial on how to set it up. I have my htdocs in Dropbox.
Does it work something like this?
define(__DIR___, 'd:documents/dropbox/yolo/swag/htdocs/myproject/test/newtest/
testphp/test_new/testincludes/1/new_folder/')
That is the directory where my project is located and it has sub folders. I want to include a file into another file that is in the parent folder.
Should I then just type:
include'__DIR__/warlock.php';
Or do I have to type something like this?
include '___DIR__/wow/newb/guidesfornabz/classes/casters/warlock.php';
You can use __DIR__ to get your current script's directory. It has been in PHP only since version 5.3, and it's the same as using dirname(__FILE__). In most cases it is used to include another file from an included file.
Consider having two files in a directory called inc, which is a subfolder of our project's directory, where the index.php file lies.
project
├── inc
│   ├── file1.php
│   └── file2.php
└── index.php
If we do include "inc/file1.php"; from index.php it will work. However, from file1.php to include file2.php we must do an include relative to index.php and not from file1.php (so, include "inc/file2.php";). __DIR__ fixes this, so from file1.php we can do this:
<?php
include __DIR__ . "/file2.php";
To answer your question: to include the file warlock.php that is in your included file's upper directory, this is the best solution:
<?php
include __DIR__ . "/../warlock.php";
I've been looking to use an executed in apache's root htdocs _DIR_ variable and be able to include other scripts containing sensitive data such as database login credentials sitting outside it. I struggled a bit trying different options but the below is working really well.
Firstly, in my apache virtual host config I set/include a full linux path to apache's htdocs (you can add more paths by appending at the end :/path/to/folder/):
php_value include_path ".:/var/www/mywebsite.ext/uat/htdocs"
Then in .htacess stored in apache's htdocs root (and git repo):
php_value auto_prepend_file "globals.php"
Both of the above can be set in .htacess although it wouldn't work well for multiple environments suchas as DEV, UAT, PRODUCTION in particular when using git repo.
In my globals.php file inside apache's htdocs I have defined a variable called DIR that's globally used by htdocs php scripts:
define('DIR', __DIR__);
Then in each file am was now able to include/require necessary files dynamically:
require_once(DIR.'/file_folder_inside/apache's_htdocs/some-file.php');
The DIR variable would always resolve to /var/www/mywebsite.ext/uat/htdocs no matter where in the tree I call it in the above example producing
/var/www/mywebsite.ext/uat/htdocs/file_folder_inside/apache's_htdocs/some-file.php.
Now, I was looking to access a php file that's sitting outside my apache's htdocs root folder which is also easily achievable by using:
require_once(DIR.'/../apache's_htdocs_parent_folder/some-file-stored-outside-htdocs-eg-snesitive-credentials.php');
This is an example of how to use __DIR__ and go to the parent directory in different PHP versions, so if you can recognize which one is old and which one is new:
For PHP < 5.3 use:
$upOne = realpath(dirname(__FILE__) . '/..');
In PHP 5.3 to 5.6 use:
$upOne = realpath(__DIR__ . '/..');
In PHP >= 7.0 use:
$upOne = dirname(__DIR__, 1);

PHP file path error for autoloader

Here is my file structure on my cpanel webserver
root
> vendor
> autoload.php
> public_html
> folder
> file2.php
> script_folder
> include_file.php
> file1.php
Inside include_file.php I have
require_once('../vendor/autoload.php');
file1.php and file2.php both contain the same call to include_file.php
require_once($_SERVER["DOCUMENT_ROOT"]."/script_folder/include_file.php");
This works fine when I run file1.php but when I run file2.php i receive the following error message.
No such file or directory Fatal error: require_once(): Failed opening required '../vendor/autoload.php' (include_path='.:/opt/cpanel/ea-php71/root/usr/share/pear') in /lvl1/lvl2/public_html/script_folder/include_file.php
However, if I change require_once('../vendor/autoload.php'); to require_once('../../vendor/autoload.php'); in include_file.php then file2.php works and file1.php does not work. It showes a similar error.
I understand this is a file path issue but, what I don't understand is why. Shouldn't the path in include_file.php always be the same no matter what file is calling it; i.e. file1.php or file2.php?
The way I see it is the the actual require_once statement is being called from include_file.php but, the behavior I'm seeing makes me think the require_once statement is being ran from file1.php or file2.php resulting in the filepath error.
Can someone please clarify?
UPDATE: inside include_file.php I have tried using:
require_once($_SERVER["DOCUMENT_ROOT"] . '/vendor/autoload.php');
and
require_once(dirname(__FILE__).'/vendor/autoload.php');
neither of these work since both return public_html as the main working directory. My vendor folder is outside the main working directory.
what is returned is this:
/script_folder/vendor/autoload.php
I understand I can simply include the correct file path at the beginning of file1.php and file2.php but, I was trying to figure out a way to reduce the number of requires I need in each file to only one by pointing them to include_file.php, then letting include_file.php do the rest of the work.
My include_file.php file contains several other require statements to other scripts on my server. Kind of like a mini autoloader. All of the other require statements work fine except the autoload.php one I'm having trouble with here.
The only difference I can see is my other scripts are within my public_html folder and my autoload.php file is located outside of public_html.
Assuming you are using Composer, you only need to require "autoload.php" once in file1.php and the file should contain a namespace like namespace App; at the top of the file below the opening PHP tag. Subsequently, file2.php should contain namespace App\folder; and included_file.php should contain namespace App\script_folder;.
The namespace should also be defined in composer.json like so:
"autoload": {
"psr-4": {
"App\\": "public_html/"
}
}
This seems to work perfectly. Guess instead of a relative path I need to use the absolute path.
include_file.php:
$autoload = str_replace('public_html','vendor/autoload.php',$_SERVER["DOCUMENT_ROOT"]);
include($autoload);
it allows me to call:
require_once($_SERVER["DOCUMENT_ROOT"]."/script_folder/include_file.php");
from any files that are in my public_html folder.
in include_file.php $_SERVER["DOCUMENT_ROOT"] returns /lvl1/lvl2/public_html (the full server path to the publicly visible folder)
then I replace public_html with the the path to my autoloader vendor/autoload.php

PHP require, dot as prefix

What is the difference between these two in PHP?
require "./vendor/autoload.php";
vs
require "vendor/autoload.php";
For both statements the autoload.php script is found, but in certain environment the autoloader itself does not find classes. I'm not trying to solve the autoloader problem itself, but try to understand why these two make it behave differently.
The . refers to the folder that you are in, it's most a unix syntax for files them for the php. I think you should use __DIR__ to prefix the included files, so you can avoid some problems with relative paths
The . gives you the ability to set the path of the included files relatively to the path of the original file that run (the file that included them).
Lets take the following structure:
/index.php
/file2.php
/folder/
/file1.php
If index.php includes file1.php, and you want file1.php to include file2.php - you can do this using require './file2.php'; (inside file1.php, which is in the inner folder).
If you use require 'file2.php'; inside file1.php you are looking for file2.php inside the folder (which will give you an error, because the file is not there).

How to use __dir__?

I want to use __dir__.
However, I can't find any good tutorial on how to set it up. I have my htdocs in Dropbox.
Does it work something like this?
define(__DIR___, 'd:documents/dropbox/yolo/swag/htdocs/myproject/test/newtest/
testphp/test_new/testincludes/1/new_folder/')
That is the directory where my project is located and it has sub folders. I want to include a file into another file that is in the parent folder.
Should I then just type:
include'__DIR__/warlock.php';
Or do I have to type something like this?
include '___DIR__/wow/newb/guidesfornabz/classes/casters/warlock.php';
You can use __DIR__ to get your current script's directory. It has been in PHP only since version 5.3, and it's the same as using dirname(__FILE__). In most cases it is used to include another file from an included file.
Consider having two files in a directory called inc, which is a subfolder of our project's directory, where the index.php file lies.
project
├── inc
│   ├── file1.php
│   └── file2.php
└── index.php
If we do include "inc/file1.php"; from index.php it will work. However, from file1.php to include file2.php we must do an include relative to index.php and not from file1.php (so, include "inc/file2.php";). __DIR__ fixes this, so from file1.php we can do this:
<?php
include __DIR__ . "/file2.php";
To answer your question: to include the file warlock.php that is in your included file's upper directory, this is the best solution:
<?php
include __DIR__ . "/../warlock.php";
I've been looking to use an executed in apache's root htdocs _DIR_ variable and be able to include other scripts containing sensitive data such as database login credentials sitting outside it. I struggled a bit trying different options but the below is working really well.
Firstly, in my apache virtual host config I set/include a full linux path to apache's htdocs (you can add more paths by appending at the end :/path/to/folder/):
php_value include_path ".:/var/www/mywebsite.ext/uat/htdocs"
Then in .htacess stored in apache's htdocs root (and git repo):
php_value auto_prepend_file "globals.php"
Both of the above can be set in .htacess although it wouldn't work well for multiple environments suchas as DEV, UAT, PRODUCTION in particular when using git repo.
In my globals.php file inside apache's htdocs I have defined a variable called DIR that's globally used by htdocs php scripts:
define('DIR', __DIR__);
Then in each file am was now able to include/require necessary files dynamically:
require_once(DIR.'/file_folder_inside/apache's_htdocs/some-file.php');
The DIR variable would always resolve to /var/www/mywebsite.ext/uat/htdocs no matter where in the tree I call it in the above example producing
/var/www/mywebsite.ext/uat/htdocs/file_folder_inside/apache's_htdocs/some-file.php.
Now, I was looking to access a php file that's sitting outside my apache's htdocs root folder which is also easily achievable by using:
require_once(DIR.'/../apache's_htdocs_parent_folder/some-file-stored-outside-htdocs-eg-snesitive-credentials.php');
This is an example of how to use __DIR__ and go to the parent directory in different PHP versions, so if you can recognize which one is old and which one is new:
For PHP < 5.3 use:
$upOne = realpath(dirname(__FILE__) . '/..');
In PHP 5.3 to 5.6 use:
$upOne = realpath(__DIR__ . '/..');
In PHP >= 7.0 use:
$upOne = dirname(__DIR__, 1);

Why include __DIR__ in the require_once?

For example, I always see autoloaders called like this:
require_once __DIR__ . '/../vendor/autoload.php';
What is the difference between that and the more concise
require_once '../vendor/autoload.php';
?
PHP scripts run relative to the current path (result of getcwd()), not to the path of their own file. Using __DIR__ forces the include to happen relative to their own path.
To demonstrate, create the following files (and directories):
- file1.php
- dir/
- file2.php
- file3.php
If file2.php includes file3.php like this:
include `file3.php`.
It will work fine if you call file2.php directly. However, if file1.php includes file2.php, the current directory (getcwd()), will be wrong for file2.php, so file3.php cannot be included.
The current accepted answer does not fully explain the cause of using __DIR__ and in my opinion the answer is wrong.
I am gonna explain why do we really need this.
Suppose we have a file structure like this
- index.php
- file3.php -(content: hello fake world)
- dir/
- file2.php
- file3.php - (content: hello world)
If we include file3.php from file2.php and run file2.php directly, we will see the output hello world.
Now when we include file2.php in index.php, when the code will start executing and it will see file2.php again including file3.php using include 'file3.php', at first the execution will look for file3.php in the current execution directory (which is the same directory where index.php is present)..Since file3.php is present in that directory, it will include that file3.php instead of dir/file3.php and we will see the output hello fake world instead of hello world.
If file3.php would not exist in the same directory, it would then include the correct dir/file3.php file which makes the accepted answer not valid because it states file3.php cannot be included which is not true. It is included.
However, here comes the necessity of using __DIR__. If we would use include __DIR__ . '/file3.php' in file2.php, then it would include the correct file even though another file3.php is present in the parent directory.
For include its possible to set some folders where PHP search automatically. When you include a file with a relative path you search in all of that folders. Its better to define the real path to prevent some errors in loading wrong files.
https://secure.php.net/manual/en/function.set-include-path.php
Then you can be sure that you load the correct file.

Categories