I am developing a website on a local test environment. From time to time I need to import classes or functions into my php pages. At first I used relative paths to import files, but for some (unexplicable) reason the PHP couldn't find those files. So I have thought it would be necessary use the following:
<?php require_once($_SERVER['DOCUMENT_ROOT'] .'/mywebsite/inc/libs/functions.php'); ?>
The problem is when I have to upload all the pages to my remote webserver, the PHP interpreter won't find functions.php in that position because there is no mywebsite subfolder , on the other hand I can't get rid of mywebsite subfolder, because that would leave me with http://localhost/inc/libs/functions.php which leads nowhere.
So that basically means I will have to manually readjust the path to make everything work. My question is: is there a way for PHP to detect the exact folder of my website so that I don't have to change paths everytime I need to upload a php file to my webserver?
What is the reason behind impossibility of use relative path?
<?php require_once(dirname(__FILE__).'/inc/libs/functions.php'); ?>
Set the base folder with all the files you want as an include path in php.ini.
That way, when you use include () or require (), it will automatically look in the included path.
www.php.net/manual/en/ini.core.php#ini.include-path
Related
I am working on a php project and I am having problems with including files.
I have a php script which is located at myapp/reports/index.php. When a form is submitted it performs an ajax post to another phpscript located at myapp/reports/phpHander/submit.php.
Submit.php then has to include a php script which is used to send an email. This is done to ensure that same code can be used over and over again without it needing to be typed for each time it is need. This php script is located at ../../administrator/classes/send.php.
Up to this point is working fine however the send.php script includes another file to get app config settings which is located in administrator/appConfig.php. The problem is this appConfig.php isn't being found even if I put in the full web address of http://localhost/myapp/administrator/appConfig.php.
What am I doing wrong. I am using the php include function to do this and its working for everything else but it seems to have a problem then including another script from a different location.
Thanks for any help you can provide.
http://localhost/myapp/administrator/appConfig.php is only URL path.
You need absolute filepath like C:/wamp/www/myapp/administrator/appConfig.php (Windows) or /var/www/myapp/administrator/appConfig.php (Linux)
Anyways best way is make a file "dirs.php" in your root application directory with constant:
define('ROOT_DIR', dirname(__FILE__));
where dirname(__FILE__) will be absolute path to your app directory.
With this knowledge you can include files in this way:
myapp/reports/index.php:
require_once('../../dirs.php');
include(ROOT_DIR . '/administrator/appConfig.php');
myapp/reports/phpHander/submit.php.:
require_once('../../../dirs.php');
include(ROOT_DIR . '/administrator/appConfig.php');
When you include another PHP script, all the paths are relative to the calling script. So, it sounds as though your script is at myapp/reports/phpHander/submit.php and includes ../../administrator/classes/send.php, which then includes another script in that same directory. In this case, you need to use the path "../../administrator/appConfig.php". Alternatively, you could use absolute paths relative to the filesystem's root.
From my previous experience, I've almost always had problems with linking files with my website projects.
For example, linking CSS styles, Javascript files and including files in PHP. The problem is, that on my PC, the directory of my project was /www/project-name/ and when I put the project on a server, the directory would be just /www/. When I uploaded the project to a server, images wouldn't show, styles wouldn't work, database connections wasn't set, functions were not defined etc...
So my question is: What is the best and most efficient way to link/include files?
Something that will work no matter what the directory of the project is, and possibly, if I include project/includes/mysql.class.php in file1.php, and I move that file to a different directory, it would still properly include project/includes/mysql.class.php
You should use relative paths.
Instead of specifying the full path ('/www/project-name/includes/whatever.php'), use a path relative to the current location:
'./includes/whatever.php'
you can define the document root directory of project and then, include all files depending on it
put
define(DOC_ROOT, realpath(direname(__FILE__));
in your front controller, and when you have to include a file
include(DOC_ROOT . "/includes/file.php");
all frameworks uses this method
I'd suggest using a relative path (eg ../style.css or ../../style.css)
The ../ references the parent directory to the current file.
This is what I do, in general.
I use root relative urls inside html (e.g. src="/images/logo.jpg"). This way I can just copy the html from one page and past it in another without having to worry about the link not working becase the other page is inside a folder.
I relative urls in css, because all the resources I use inside the css, like images, I keep in the same folder as the css file (or a sub-directory of it). I mostly do this because it is shorter (url(img/background.jpg); vs. url(/css/img/background.jpg);). Minor added bonus is you could just copy the css folder to create a new theme based on the old one, without having to change all the urls in the css.
In PHP I use include($_SERVER['DOCUMENT_ROOT'] . '/includes/mysql.php');. You can just copy past the code into another file in another folder and it will still work.
The only time I rarely need to hardcode paths is inside htaccess.
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']
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"];
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.