I need help with writing a php code that allows you to locate files outside a current folder.
supposing I have this directory
......./folders/codes
where my current file index.php is but then I want to reference a file in folders via the file in code, how do I go about that?
I thought i could use the HTML/CSS way where ../ would move you down one folder but it did not work when i tried it
require "../Login.php";------------------it failed
dirname return you the path up to your parent directory.
Try to use following code
require dirname(dirname(__FILE__)).'Login.php';
You sure your path is correct?
A common mistake is to overlook from where you're require-ing.
If, for example, you were to have a script that was included in another script, the relative path would not be the one you'd think it would be.
Try
echo realpath(dirname(__FILE__));
To see if you didn't make that mistake.
Not sure if this is appropriate, but it didn't fit in a comment.
Related
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.
I just stumbled upon a (at least for me) new weird behavior of paths while using php functions with pure php or ajax calls.
If I use just php the path in the php function is like:
require_once('wp-content/themes/xxx/tcpdf/tcpdf.php');
but if I use the exact same function with an ajax call, the path needs to be like this to make it work:
require_once('../tcpdf/tcpdf.php');
Can you explain me why this is so? Thank you very much!
The reason that you are getting that behavior is because all the includes are occuring from the root of the wordpress install so you are saying do down the directory structure several layers before you get to the file. Breaking it down it does like this.
wp-content/ Go down one directory level from the file i'm in
themes/ Then go down into the themes directory
xxx/ Then go to the xxx directory
tcpdf/ Then go to the tcpdf directory
tcpdf.php This is the file you want
When you are doing the second include you are in a directory that shares a parent with wp-content/themes/xxx/tcpdf/ so what you are saying is
../ Go up one directory level
tcpdf/ Go into the tcpdf directory
tcpdf.php This is the file you want
I guess when you are using it without an AJAX call, you are including it from some other file, that can make the difference.
However I recommend storing the application root directory in a constant (e.g. ROOT) and then you include everything relative to ROOT.
Redefine the include path to set_include_path ( APP_ROOT ). By doing so, ALL includes/requires will be relative to the application root that you will define in the constant APP_ROOT.
PHP normally has the current directory as include path, which can lead to problems like this you're having.
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.
I have a web application in php. I have a header.php file where I have the opening html tag, meta data, css,js file includes.
I have multiple folders in this application. I have given relative paths to the css,js files in the header.php. The problem I am facing is, when I include this header.php file in some other file say, ./test-folder/my-file.php, the relative paths break.
so to solve this i have given absolute paths where ever needed. But I have to change these paths every time I upload on to server. Can this be done in any other way?
Thanks in advance
Anji
Do not use static value for path instead define a constant for document root and use that constant
define('ROOT_PATH',$_SERVER['DOCUMENT_ROOT']);
While including files you can use this constant.
include ROOT_PATH.'/some_dir/file.php';
You have bad architecture in your application. Try to search info about MVC.
This answer may be useful: https://stackoverflow.com/questions/5721353/what-is-good-neat-architecture-in-programming/5793753#5793753
So:
change architicture,
use autoload
Relative paths are relative to the current working directory (cwd). If you just include another file that cwd does not change.
If you want to have paths that are (somewhat) relative to the current script file path you can use e.g.
require dirname(__FILE__).'/some_dir/file.php';
or as of php 5.3
require __DIR__.'/some_dir/file.php';
see also: http://docs.php.net/language.constants.predefined
If I understood your question right, you just would like to know the root folder your application without the need to hardcode it.
The easier way is to define a constant as Shakti has answered.
However, you could actually have a file with a unique name such as "foobar" in the root folder, then walk up the tree from current directory until you find foobar.
In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:
/images/some_image.jpg
I can put that path in any file in any subdirectory, and it will point to the right image.
With PHP, I tried something similar:
include("/includes/header.php");
...but that doesn't work.
I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:
Using a . in the include path allows for relative includes as it means the current directory.
Relative includes are exactly what I don't want.
How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)
Clarification
My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)
Update
I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.
One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.
Anyway, problem solved! :)
What I do is put a config.php file in my root directory. This file is included by all PHP files in my project. In that config.php file, I then do the following;
define( 'ROOT_DIR', dirname(__FILE__) );
Then in all files, I know what the root of my project is and can do stuff like this
require_once( ROOT_DIR.'/include/functions.php' );
Sorry, no bonus points for getting outside of the public directory ;) This also has the unfortunate side affect that you still need a relative path for finding config.php, but it makes the rest of your includes much easier.
One strategy
I don't know if this is the best way, but it has worked for me.
$root = $_SERVER['DOCUMENT_ROOT'];
include($root."/path/to/file.php");
The include_path setting works like $PATH in unix (there is a similar setting in Windows too).It contains multiple directory names, seperated by colons (:). When you include or require a file, these directories are searched in order, until a match is found or all directories are searched.
So, to make sure that your application always includes from your path if the file exists there, simply put your include dir first in the list of directories.
ini_set("include_path", "/your_include_path:".ini_get("include_path"));
This way, your include directory is searched first, and then the original search path (by default the current directory, and then PEAR). If you have no problem modifying include_path, then this is the solution for you.
There is nothing in include/require that prohibits you from using absolute an path.
so your example
include('/includes/header.php');
should work just fine. Assuming the path and file are corect and have the correct permissions set.
(and thereby allow you to include whatever file you like, in- or outside your document root)
This behaviour is however considered to be a possible security risk. Therefore, the system administrator can set the open_basedir directive.
This directive configures where you can include/require your files from and it might just be your problem.
Some control panels (plesk for example) set this directive to be the same as the document root by default.
as for the '.' syntax:
/home/username/public_html <- absolute path
public_html <- relative path
./public_html <- same as the path above
../username/public_html <- another relative path
However, I usually use a slightly different option:
require_once(__DIR__ . '/Factories/ViewFactory.php');
With this edition, you specify an absolute path, relative to the file that contains the require_once() statement.
Another option is to create a file in the $_SERVER['DOCUMENT_ROOT'] directory with the definition of your absolute path.
For example, if your $_SERVER['DOCUMENT_ROOT'] directory is
C:\wamp\www\
create a file (i.e. my_paths.php) containing this
<?php if(!defined('MY_ABS_PATH')) define('MY_ABS_PATH',$_SERVER['DOCUMENT_ROOT'].'MyProyect/')
Now you only need to include in every file inside your MyProyect folder this file (my_paths.php), so you can user MY_ABS_PATH as an absolute path for MyProject.
Not directly answering your question but something to remember:
When using includes with allow_url_include on in your ini beware that, when accessing sessions from included files, if from a script you include one file using an absolute file reference and then include a second file from on your local server using a url file reference that they have different variable scope and the same session will not be seen from both included files. The original session won't be seen from the url included file.
from: http://us2.php.net/manual/en/function.include.php#84052
hey all...i had a similar problem with my cms system.
i needed a hard path for some security aspects.
think the best way is like rob wrote. for quick an dirty coding
think this works also..:-)
<?php
$path = getcwd();
$myfile = "/test.inc.php";
/*
getcwd () points to:
/usr/srv/apache/htdocs/myworkingdir (as example)
echo ($path.$myfile);
would return...
/usr/srv/apache/htdocs/myworkingdir/test.inc.php
access outside your working directory is not allowed.
*/
includ_once ($path.$myfile);
//some code
?>
nice day
strtok
I follow Wordpress's example on this one. I go and define a root path, normally the document root, and then go define a bunch of other path's along with that (one for each of my class dirs. IE: database, users, html, etc). Often I will define the root path manually instead of relying on a server variable.
Example
if($_SERVER['SERVERNAME'] == "localhost")
{
define("ABS_PATH", "/path/to/upper/most/directory"); // Manual
}
else
{
define("ABS_PATH, dirname(__FILE__));
// This defines the path as the directory of the containing file, normally a config.php
}
// define other paths...
include(ABS_PATH."/mystuff.php");
Thanks - this is one of 2 links that com up if you google for php apache windows absolute path.
As a newbie to intermed PHP developer I didnt understand why absolute paths on apache windopws systems would be c:\xampp\htdocs (apache document root - XAMPP default) instead of /
thus if in http//localhost/myapp/subfolder1/subfolder2/myfile.php I wanted to include a file from http//localhost/myapp
I would need to specify it as:
include("c:\xampp\htdocs\myapp\includeme.php")
or
include("../../includeme.php")
AND NOT
include("/myapp/includeme.php")
I've come up with a single line of code to set at top of my every php script as to compensate:
<?php if(!$root) for($i=count(explode("/",$_SERVER["PHP_SELF"]));$i>2;$i--) $root .= "../"; ?>
By this building $root to bee "../" steps up in hierarchy from wherever the file is placed.
Whenever I want to include with an absolut path the line will be:
<?php include($root."some/include/directory/file.php"); ?>
I don't really like it, seems as an awkward way to solve it, but it seem to work whatever system php runs on and wherever the file is placed, making it system independent.
To reach files outside the web directory add some more ../ after $root, e.g. $root."../external/file.txt".