How can we include php files without specifying the subfolder path

Multi tool use
How can we include php files without specifying the subfolder path
Normally we use the following code to include php files inside each other:
<?php
include_once 'include/config.php';
// OR
include 'include/config.php';
// OR
include_once $_SERVER['DOCUMENT_ROOT'].'include/config.php';
// ect...
?>
But the above codes only apply if the php files are in the root file. I mean, if we move our files into a subfolder. We need to make a change to the code we included in the php files. For example like this:
<?php
include_once 'subfolder/include/config.php';
// OR
include 'subfolder/include/config.php';
// OR
include_once $_SERVER['DOCUMENT_ROOT'].'/subfolder/include/config.php';
// ect...
?>
What I'm saying is that when we move our php files into the subfolder, then include_once want to see subfolder name like (include_once 'subfolder/include/config.php';
). This is a challenging situation because we need to do this for the included page in many files.
include_once 'subfolder/include/config.php';
For example i include the include_once $_SERVER['DOCUMENT_ROOT'].'/functions/includes.php';
from the index.php
and also included this includes.php file from all php files like header.php, posts.php, and ajax_post.php
. It is working fine from the root folder but if we move the files in the subfolder then include.php file not including without subfolder name.
include_once $_SERVER['DOCUMENT_ROOT'].'/functions/includes.php';
index.php
header.php, posts.php, and ajax_post.php
Maybe it is also possible to do this with .htaccess
.
.htaccess
I have made this htaccess code maybe you have a solution with htaccess. I must be say i have tryed to use RewriteBase /subfoldername/
but include files didn't worked.
RewriteBase /subfoldername/
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{THE_REQUEST} /index.php [NC]
RewriteRule ^(.*)index.php$ /$1 [L,R=302,NC,NE]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^group/([w-]+)/?$ sources/group.php?group_username=$1 [L,QSA]
RewriteRule ^profile/([w-]+)/?$ sources/user_profile.php?username=$1 [L,QSA]
RewriteRule ^profile/(followers|friends|photos|videos|locations|musics)/([w-]+)/?$ sources/$1.php?username=$2 [L,QSA]
RewriteRule ^admin/(.*)$ admin/index.php?page=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
RewriteRule ^(.+?)/?$ index.php?pages=$1 [L,QSA]
. My responsibility is, how can we include php files without subfolder name?
why dont you use relative paths
– sumit
Dec 13 '17 at 20:55
@cteski hmm it looks like a nice solution. I am going to test it.
– Azzo
Dec 13 '17 at 20:58
I usually include relative to document root using the DIRECTORY_SEPARATOR constant. Makes it all clean and portable between operating environments.
include_once($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR."include_folder".DIRECTORY_SEPARATOR."included_file.php");
– Typel
Dec 13 '17 at 20:59
include_once($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR."include_folder".DIRECTORY_SEPARATOR."included_file.php");
@Typel What is
include_folder
, I am asking My responsibility is, how can we include php files without subfolder name but your answer have subfolder name??– Azzo
Dec 13 '17 at 21:02
include_folder
10 Answers
10
You can use auto_prepend_file
directive in your .htaccess to make a .php
file included before all of your php files.
auto_prepend_file
.php
If you're using mod_php
then have this line in your .htaccess:
mod_php
php_value auto_prepend_file "/Applications/MAMP/htdocs/script/env.php"
Note that for PHP-FPM
you need to have these equivalent line in your .user.ini
file:
PHP-FPM
.user.ini
auto_prepend_file = "/Applications/MAMP/htdocs/script/env.php"
Then create a new file env.php
in your project base directory with just one line:
env.php
<?php
$baseDir = __dir__ . '/';
?>
This line sets a variable $baseDir
that has value of your project base directory i.e. /Applications/MAMP/htdocs/script/
OR /Applications/MAMP/htdocs/subdir/script/
$baseDir
/Applications/MAMP/htdocs/script/
/Applications/MAMP/htdocs/subdir/script/
Then use this variable $baseDir
anywhere you have to include other files such as:
$baseDir
include_once $baseDir.'functions/includes.php';
include_once $baseDir.'functions/get.php';
I think this your answer will help many people. And thank you very much. You are the best for me
– Azzo
Jun 1 at 11:23
Auto prepend can be very dangerous, be sure not to have any output from an auto prepend script, as this can cause header issues, and issues in some cases with downloads.
– ArtisticPhoenix
Jun 8 at 17:33
Agree with that though this case is fairly simple as OP just wants access to a single global.
– anubhava
Jun 8 at 18:13
@anubhava Dear your answer is working on the localhost but when i upload the files from the online server i get an 500 Internal Server Error. Can you help me about it please ?
– Azzo
Jul 1 at 7:54
@Azzo: This answer would work for php-gpm also with a minor change. See this post: medium.com/@jacksonpauls/…
– anubhava
Jul 1 at 9:53
__DIR__
is certainly what you are looking for. Use it to provide relative paths for required files. I would highly suggest using require_once
or include_once
for all library files.
__DIR__
require_once
include_once
include_once dirname(dirname(__DIR__))."/include/config.php";
__DIR__
wont work in this case, because its __DIR__.'/include/config.php'
vs __DIR__.'/subfolder/include/config.php'
If that wasn't the case ( the config.php was in the same folder as this file, a relative path would work )– ArtisticPhoenix
Dec 23 '17 at 9:24
__DIR__
__DIR__.'/include/config.php'
__DIR__.'/subfolder/include/config.php'
You have to use function set_include_path()
and somewhere in your bootstrap.php
or index.php
add next code:
set_include_path()
bootstrap.php
index.php
<?php
$path = '/usr/pathToYourDir';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
now everywhere below you can write this:
include_once 'include/config.php';
// or
include_once 'include/db/index.php';
// etc
And in case you need to move your code into another directory - you have only to change value of path varibalbe $path = '/usr/pathToYourDir';
to new path to your directory.
$path = '/usr/pathToYourDir';
Ok, I'm not a fan of doing this, but it will get the job done, as requested:
$newpath="";
$dirs = array_filter(glob('*'), 'is_dir');
foreach ($dirs as $location) {
$newpath .= PATH_SEPARATOR . $location;
}
set_include_path(get_include_path() . $newpath);
The above code will find all subfolders from where this file is running, and add them all to the current include path. by changing the glob from:
glob('*')
to
glob('includes/*') or glob('includes' . DIRECTORY_SEPARATOR . '*')
You can restrict it to only subfolders under includes.
The above is not tested, I just threw the code together, but it illustrates a way to do what you're asking for.
I would still recommend putting files in determined locations rather than trying to include them from anywhere.
This is how I would do it.
//----- some global location like index.php
if(!defined("CONFIG_PATH")) define("PATH_CONFIG", __DIR__."/include/");
//------------ then later in some other file
if(!defined("CONFIG_PATH"))die("Config path is not defined.");
include_once CONFIG_PATH.'config.php';
Then when you change it you just update
if(!defined("CONFIG_PATH")) define("PATH_CONFIG", __DIR__."/include/subfolder/");
I would say this is the "Traditional" way to do it, and it's perfectly fine to use a global constant for this. It's not something you want changing at run time. You need access to it in many places, potentially. You can check if your files are accessed properly .. etc.
Many many many, MVC frameworks do it this exact way.
Globals are globals and they can make integrating other frameworks/libraries/scripts difficult without adequate name spacing.
– Progrock
Dec 23 '17 at 10:28
Refer this link hope it helps
http://www.geeksengine.com/article/php-include-path.html
Here's an example of an approach that requires your files upfront via the auto_prepend_file directive.
bootstrap.php
:
bootstrap.php
<?php
$require_upfront = function($dir) {
require_once $dir . '/one.php';
require_once $dir . '/two.php';
};
$require_upfront(__DIR__ . '/inc');
Add to php config, here .htaccess example:
php_value auto_prepend_file "/abs/path/to/bootstrap.php"
This works fine tell you do a download and realize something in bootstrap.php is outputting stuff. Then it blows up your headers or includes content in your download file. It's also hard to trackdown where that content came from.
– ArtisticPhoenix
Dec 23 '17 at 9:34
Yes it's good to be aware of the limitations of any approach. Good documentation/commenting would help here.
– Progrock
Dec 23 '17 at 10:30
I had a network guy "fix" some stuff with our reverse proxy with that took us about 2 weeks to figure it out.
– ArtisticPhoenix
Dec 23 '17 at 10:42
You would be surprised how hard it is to fine
n<?php
line return before opening PHP tags. Or even <?php ... ?>n
at the end. I never close my PHP tags now... lol– ArtisticPhoenix
Dec 23 '17 at 10:47
n<?php
<?php ... ?>n
Trailing and preceding whitespace output/issues is not particular to the solution I present here.
– Progrock
Dec 23 '17 at 12:45
If you have the file's name unique in all server, you can make a research of this using a research like this.
I think that this solution isn't better when this script run a lot of, but you can include if the include function fails, using try and catch (if you use this method watch the php version) or if you know that this path change once a day you can make a file which is launched with routine.
If you make this, you need to store this path, but I don't know if there is a method for make global variable. My solution is to store or in a DB or in a file.
I hope I have helped you.
I remember that this method don't work if you have different file into different folder with the same name.
– L. Ros.
Dec 23 '17 at 7:59
What I understand from the answer https://stackoverflow.com/a/50632691/7362396 is that you need to include files based on the directory of the entrypoint script.
A solution for this without the need for Apache or php.ini auto_prepend_file
could be to use getcwd()
. It returns the current working directory, which should be the path of the entrypoint/main script, even when called in included files.
auto_prepend_file
getcwd()
Can you try if simply using getcwd()
instead of $baseDir
works?:
getcwd()
$baseDir
include_once getcwd().'/functions/includes.php';
include_once getcwd().'/functions/get.php';
Using Apache to fix your app is solving it at the wrong level.
If you have to update a bunch of files in your code when the location of a file changes, that is your code telling you that you have made a bad architectural decision. So fix the actual problem and stop repeating yourself.
Define where your includes live in one place, and then when needed, update that one place accordingly.
One way to do this is set a constant at the root of your app. This assumes you have a bit of code at the root of your app that is called on every page. This would likely be index.php
or a script included by index.php
:
index.php
index.php
// index.php or a file included by index.php
const MY_INCLUDE_PATH = __DIR__ . '/path/to/subfolder`
Then your other scripts can call include using the constant:
// some other script included to handle the page
include MY_INCLUDE_PATH . '/config.php';
include MY_INCLUDE_PATH . '/some-other-include.php';
Although if they all want to include the config.php
file, maybe just go ahead and include it in your index.php
.
config.php
index.php
This is not a "bad" global you want to avoid. It is using constants as they are intended. Constants are part of the namespace, if you are using a namespace for your app.
This assumes there is one include subfolder that sometimes changes places and a script somewhere that is a part of every request. Is that correct? If not, please post your directory structure.
A function would also work, and could include logic based on things such as the path of the calling script:
// index.php or a file included by index.php
my_include_function($path) {
//do stuff
}
The other scripts might call this function like so:
// some other script included to handle the request
my_include_function(__FILE__);
Then when things change, you simply update one function in one file.
This all assumes you have an index.php
or similar script that handles every request and can be the single point of control for defining the function or constant. If that's not the case, it should be!
index.php
Updating your code to use a router (here is one) would take maybe 10 minutes and potentially simplify that gnarly .htaccess file you posted.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
One way is to configure those paths using set_include_path.
– cteski
Dec 13 '17 at 20:55