Having issues with getting root path directory from different folders - php

I am trying to connect a certain header file for different files in different folders. The problem is when having the same file included in for example /backend it will be easily called directly (as the index is also in /backend) but when calling it from backend/pages it doesnt recall the link structure anymore resulting in a deadlink.
I have tried every possible thing with ../ and different header files but that is a no go. Trying to find a solution such as the url below comes really close but yet I cannot seem to figure it.
Root path variable in a PHP project
What would be the best way to include the root automatically in an include or require for example.

If you're using a front controller (like an index.php file) that is starting and executing your entire application you can just set a constant there like define('APP_ROOT', __DIR__); and that'll set the root to be your front controller.
You can access your header file from anywhere then by doing APP_ROOT . "/includes/header.php"
If you are not using a front controller, then you can set this in each file. So for backend/pages it'd be something like ./../includes/header.php. or better still, use $_SERVER['DOCUMENT_ROOT'] to get the root of your application as provided by your web server vhosts config. (Apache of NGINX most likely)
$_SERVER['DOCUMENT_ROOT'] . "/app/backend/includes/header.php" for example.

What would be the best way to include the root automatically in an include or require for example.
I'm not aware of any method to do that without modifying PHP itself and re-compiling from source, but I could be wrong. Your root path will always be stored in $_SERVER['DOCUMENT_ROOT'].
I think what you might want to look into is autoloading and more specifically PSR-4 and composer.

Related

Is it a good idea to use $_SERVER['DOCUMENT_ROOT'] in includes?

Is this, for example, a good idea?
require_once($_SERVER['DOCUMENT_ROOT'].'/include.php');
If you have two virtual hosts on the same server, one for live and one for development, with different Apache DocumentRoots, this would avoid having to include absolute paths when the source of the include is unknown, and may be in any directory.
(Note: file paths in the following section are relative to the web root. They would in fact be like /var/www/app/core/init.php, where /var/www/app is the web root)
For instance: I have an /core/init.php which is called using relative paths from places all over the website (/file.php, /dir/file.php or /dir/dir/file.php).
This init.php then includes several function pages, in the fund directory, a subdir of /core (as in /core/func/userfunctions.php).
So, in init.php, I can use the $_SERVER method, because it breaks if I use a relative path and try to call functions from a page like /dir/file.php.
I can't see any problem with it, but in general what could go wrong?
I've seen cases where $_SERVER['DOCUMENT_ROOT'] is not set or is not what you would expect (i.e. not set in CLI or old IIS, or invalid in certain CGI setups).
For that reason you can use dirname(__FILE__) to obtain the path of the script that line is called in. You can then reference relative paths from there e.g.
include dirname(__FILE__) . '/../../other/file.php';
I go with the above method when the directory structure of the files is known and is not subject to change.
If DOCUMENT_ROOT is not available, the following is a suitable replacement:
substr($_SERVER['SCRIPT_FILENAME'], 0, -strlen($_SERVER['SCRIPT_NAME']));
You don't need to do this. PHP looks for the included file in the document root by default.
You can use set_include_path($new_include_path) to change this behaviour, or edit include_path in the php config file.
Also, from http://php.net/manual/en/reserved.variables.server.php:
'DOCUMENT_ROOT'
The document root directory under which the current script is executing, as defined in the server's configuration file.
For example, if you use URL rewriting, you will be very happy when you find out that the includes in your /there/are/so/many/paths/in/the/url/of/this/ page are still working!

PHP how to find application root?

I'm having problems with my include files. I don't seem to be able to figure out how to construct my URLs when I use require_once('somefile.php'). If I try to use an include file in more than one place where the directory structures are different, I get an error that the include file cannot be found.
In asp.net, to get my application root path, I can use ~/directory/file.aspx. The tild forward slash always knows that I am referencing from my website root and find the file no matter where the request comes from within my website. It always refers back to the root and looks for the file from there.
QUESTION: How can I get the root path of my site? How can I do this so I can reuse my include files from anywhere within my site? Do I have to use absolute paths in my URLs?
Thank you!
There is $_SERVER['DOCUMENT_ROOT'] that should have the root path to your web server.
Edit: If you look at most major php programs. When using the installer, you usually enter in the full path to the the application folder. The installer will just put that in a config file that is included in the entire application. One option is to use an auto prepend file to set the variable. another option is to just include_once() the config file on every page you need it. Last option I would suggest is to write you application using bootstrapping which is where you funnel all requests through one file (usually with url_rewrite). This allows you to easily set/include config variables in one spot and have them be available throughout all the scripts.
I usually store config.php file in ROOT directory, and in config.php I write:
define('ROOT_DIR', __DIR__);
And then just use ROOT_DIR constant in all other scripts.
Using $_SERVER['DOCUMENT_ROOT'] is not very good because:
It's not always matching ROOT_DIR
This variable is not available in CGI mode (e.x. if you run your scripts by CRON)
It's nice to be able to use the same code at the top of every script and know that your page will load properly, even if you are in a subdirectory. I use this, which relies on you knowing what your root directory is called (typically, 'htdocs' or 'public_html':
defined('SITEROOT') or define('SITEROOT', substr($_SERVER['DOCUMENT_ROOT'], 0, strrpos($_SERVER['DOCUMENT_ROOT'], 'public_html')) . 'public_html');
With SITEROOT defined consistently, you can then access a config file and/or page components without adapting paths on a script-by-script basis e.g. to a config file stored outside your root folder:
require_once SITEROOT . "/../config.php";
You should use the built in magic constants to find files. __FILE__ and __DIR__. If you are on PHP < 5.3 you should use dirname(__FILE__)
E.g.
require_once __DIR__.'/../../include_me.php';
$_SERVER['DOCUMENT_ROOT'] is not always guaranteed to return what you would expect.
Define it in a config file somewhere.
Assuming you're using an MVC style where everything gets routed through a single index.php then
realpath('.');
Will show you the path to the current working directory (i.e where index.php is)
So then you can define this as
define('PROJECT_ROOT', realpath('.'));
If it's not MVC and you need it to work for files in subfolders then you can just hard code it in a config file
define('PROJECT_ROOT', 'C:/wamp/www/mysite');
Then when including something you can do;
include PROJECT_ROOT . '/path/to/include.php';
You could alternativly set the base directory in your .htaccess file
SetEnv BASE_PATH C:/wamp/www/mysite/
Then in PHP you can reference it with $_SERVER['BASE_PATH']
Try this:
$_SERVER['DOCUMENT_ROOT']

how to use config file from a subdirectory while it is been kept at root directory in PHP

I am developing a web application. contents are:
root dir (/var/www/)
config.php
index.php
details.php
admin dir (/var/www/admin)
admin.php
I have included config.php file into index.php, details.php in root directory using require_once('config.php') as this file contains database passwords, styles, images directory paths..
how can i include that config files in my admin/admin.php file so that one config file can be used in anywhere(even in subdirectories) of my web application. Will it make any difference for the value of define('APP_BASE_PATH', dirname(__FILE__)); when same config file is used by all files in the web application.
if i am wrong somewhere then please get me right.
If your server properly configured, just
include $_SERVER['DOCUMENT_ROOT']."/config.php";
anywhere
You have also 2 other possible ways.
a Front controller setup, where ALL user requests going into one file. And ths one going to include all others from their subdirectories. Personally I don't like it cause this front file become a mess. Though it's widely used.
I decided not to mention it because noone would use a hardcoded full path anyway.
Update after clarification in comments: You are looking for a way to include a central configuration file from anywhere in your project's folder structure.
#Col. Shrapnel shows one way, DOCUMENT_ROOT. It's the only way to use an "absolute" path from a nested folder structure. It has the limitation I describe above, but it's fine otherwise.
If you want maximum portability (i.e. the possibility to run the app with e.g. www.example.com/myapp/version_1 as its root directory), you would have to use relative references from within your folder structure to "climb down" to the config file, e.g. ../../config.php that will work reliably too, although be a bit cumbersome e.g. if you move a script to a different folder and you have to update the relative path.
you can use the same config file every time... using "/" will take you back to the root directory... so in admin/admin.php use this:
require_once("/config.php");
you can use "../" to take you up one directory eg:
require_once("../config.php");
was this what you were looking for?

How can I control DOCUMENT_ROOT to work on localhost and live server?

To keep URLs working in version-controlled projects, I've been using $_SERVER['DOCUMENT_ROOT']. The problem is, I develop projects within a folder, so I get this:
$_SERVER['DOCUMENT_ROOT'] . '/folder/path/to/file.php'
When I go live, I generally simply want the following:
$_SERVER['DOCUMENT_ROOT'] . '/path/to/file.php'
I know there are bigger problems in the world than having to remove and add this folder name, but is there a way I can easily automate this? Can I somehow set my document root locally to include the folder I'm working in? Do I have a fundamental misunderstanding of the way things are working? Kind of new at this stuff, and looking to learn as much as possible and really grok the "why."
Thanks so much!
Instead of using $_SERVER['DOCUMENT_ROOT'], why not declare a constant which always holds the root of your web application?
<?php
define('ABSPATH', dirname(__FILE__));
Put the following code in a file located in the root folder of your application and include it on every page load.
Then, you can simply always do $path = ABSPATH . '/path/to/file.php'; regardless of if your local copy is in a sub-directory folder or not.
If your application already has a file which is included on every page load, you can simply drop the code above in that file and it will work.
Just note that you may have to add additional dirname() calls depending on where that file is located. Add one for each directory you pass from the root of your webapp.
For example, if your webapp is located in /webapp/ and your "global include" is located in /webapp/includes/framework/init.php, then the above code needs to be modified as such:
define('ABSPATH', dirname(dirname(dirname(__FILE__))));
ie.: 2 additional dirname() calls due to two additional folders from the webapp root (includes/framework)
Clarification
The code above is meant to be in one file, and one file only in your web application. That file needs to be included on each page load.
If you already have a file which is included before any processing (such as a configuration file or other), you may copy and paste that code in that file.
The number of dirname() calls depends on how deep the file you copied and pasted the
code in is relative to the root directory of your web application. For the examples above, assume the root of your web application is represented by ~.
If you copy-paste my code into ~/abspath.php, then you need one dirname() call.
If you copy-paste my code into ~/includes/abspath.php, then you need two dirname() calls.
If you copy-paste my code into ~/includes/config/abspath.php, then you need three dirname() calls. Now let's just say that's its final location.
In ~/index.php, you do the following:
<?php
require_once('includes/config/abspath.php');
and you have access to ABSPATH.
In ~/dir/someOtherPage.php you do the following:
<?php
require_once('../includes/config/abspath.php');
and you have access to ABSPATH.
This is why I'm saying that if you already have a file which is included on each page load, its simpler just to drop the above code in it. Just make sure you modify the amount of dirname() calls accordingly. Again, this code is meant to be in ONLY ONE FILE.
declare below line in any of root file (index.php)
$_SESSION["uploads_base_url"]=dirname(__FILE__);
and you can now use this in any of file where uploads needed.
echo $uploads_base_url=$_SESSION["uploads_base_url"];

How to use a PHP includes across multiple directories/sub directories with relative paths

I'm having difficulty with paths in a cms system I'm attempting to build, I've basically got a folder with my header.php and footer.php files inside.
These are included in index.php and work fine. But then when I attempt to use the same includes in a file within my admin sub directory, the images and CSS are broken, obviously because the relative path is now wrong.
So my question is, how can I overcome this?
After reading some of the other questions on here and various other sources, I think absolute paths are the way forward, but I've always used relative paths, so the various concepts of using config files to specify an absolute path are confusing me.
I usually manage to work things out for myself, but it's been a long day and Im stumped!
i usualy have a file called config in my application root and in it i define a constant for base path and a few others:
define('APP_BASE_PATH', dirname(__FILE__));
define('APP_FUNCTIONS_PATH', APP_BASE_PATH . '/functions');
and i include my files like
include (APP_BASE_PATH . 'includes/another_file.php');
include (APP_FUNCTIONS_PATH . '/function_file.php');
that way i can place my aplication in whatever directory, plus i can move files around without to much worries.
also using full path makes the include faster
I prefer setting the environment variables (in Apache, using .htaccess or the .conf). This way you can move all your files freely anywhere in webroot and it will have access to those variables.
SetEnv lib /library/folder/
SetEnv public /my/web/root/
SetEnv environ DEVELOPMENT
Also you can use the variable named 'environ' mentioned in the above .htaccess snippet to include a server specific file as config file in all of your scripts and set various variables there.
require_once getenv('lib')."Configs/Config_".getenv('environ').".php";
Enjoy your freedom!
or...
include($_SERVER['DOCUMENT_ROOT'] .'/includes/header.php');
Relative and absolute paths in PHP are a bit fragile because they depend not just on the current directory of the including file, but also the current working directory.
So you need a two-part solution.
Firstly, you need a redirector. Basically, this is an include file that serves as a single-point-of-call for all other pages. Its job is to go and include the rest of your infrastructure. All your pages call this redirector and only this redirector (but you can chain them).
This redirector now does
include_once dirname(__FILE__).'/include/include.php';
This lets you change your infrastructure's include file, or location and all you have to update is one file. The dirname() call solves all the relative and absolute problems and has it look for the next step relative to itself. And by definition this only changes when you change it, so it will always work.
The second part is a custom includer so you can call content by name with a function and it goes and gets the right file. Burying this in your infrastructure directory is where is goes. It then becomes a black-box that the pages outside this area call without knowing and without needing to know how it works or where it is. That removes the need for path constants to include page fragments because you have one place doing it all for you.
I have had this similar issue and posted this query in this link in SO. The URL is : Issue with PHP include with global path.
While working on the solutions given by people and looking at various threads (including this one - which I had quoted in my solution at the bottom section of my post), I had a way! I had posted the solution as well. It may help some one who is facing a similar issue.

Categories