php included files and directories - php

Lets say I have two files in directory new_folder: a.php and b.php
In the file of a.php there is a statement:
include_once 'b.php'
In addition, I have a file demo.php in a parent folder, in the demo file there is a statement:
include_once 'new_folder/a.php'
I.E. the folder structure is:
demo.php
new_folder
- a.php
- b.php
Why if I write in the a.php file:
include_once 'b.php' - correct path
include_once './b.php' - incorrect path
include_once 'new_folder/b.php' - incorrect path

Try This
require_once('../b.php');

my answer is based on php.net:
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.
that means that if I write in a.php: include_once 'b.php' ; and then include a.php in demo.php then first it looks for the file in the include_path, then it will look for the file in the directory of the calling script (a.php), and only then it will look for the file in the working directory (that is the directory of the file that we run and starts all the includes- demo.php)
edit: I tried running it and found out that first if there is b.php in the working directory then it will include it and not the b.php from the calling scrip's own directory.
the last check for the file is in the new_folder (the calling script's own directory)

Related

PHP include file that includes a file up the directory tree

I have this directory tree:
test.php
foodir
`---- foo.php
bardir
`---- bar.php
When I open test.php, I include foo.php. Then, I want foo.php to include bar.php.
test.php:
include 'foodir/foo.php';
foo.php:
include '../bardir/bar.php';
However, when I open test.php, I get:
Warning: include(../bardir/bar.php): failed to open stream: No such file or directory
I noticed that if I change my directory tree to:
test.php
foodir
`---- foo.php
---- bardir
`---- bar.php
And then change foo.php to:
include 'bardir/bar.php';
Everything works. It appears that I can include files relative to the currently included file.
However, why am I not able to travel up the directory tree of that file?
Edit:
I know that I can put include 'bardir/bar.php' in foo.php. It would search for bar.php in the location of test.php. However, that doesn't solve my problem if I include foo.php from a file in a directory other than the one where test.php is. That's because in that other directory, bardir/bar.php wouldn't exist.
When you use include 'foodir/foo.php'; that file is now basically running in the "scope" of test.php.
Therefore, the include inside that file include '../bardir/bar.php';
will go up one folder and THEN searching for bardir, which isnt there:
(it's looking for this arrangement:)
parent/test.php
parent/foodir
`---- foo.php
bardir
`---- bar.php
so, the correct include to use inside foo.php would be include 'bardir/bar.php';
in short: If you open test.php all include-paths used in any included file should be relative to the location of test.php - not to their actual location.
ps.: As mentioned in the comments: Includes are first checking the defined include-dir, only if there isn't a match, the path is considered "relative".
Simply do:
include dirname(__DIR__).'/bardir/bar.php';
__DIR__ is the absolute directory path of the file where this constant is used/called (no matter where it's included from), thus __DIR__ is equal to /full/absolute/path/foodir. and dirname(__DIR__) goes one directory up of the path so dirname(__DIR__) /full/absolute/path, and where the bar.php resides is /full/absolute/path/bardir. That's what we want, that's what we get.
This way you don't have to worry include path relativity. It will work any case, no matter where foodir/foo.php is included from
"When you use include it assume the base directory to look for
file is the directory of current file"
So when you have to include file from the another dir you have to specify the relative path from parent directory as here "Base" to include so let say for
Base -> A
->file1.php
->B
->file1.php
we will use
include "../A/file1.php";
for Adding files from A and vice-versa.
Assume ../ as the one level up of specified dir
also you can use __DIR__ like build in constants for getting the dir name of current file

why two level PHP include only work on current directory?

Let me demonstrate my file structure first.
/www/
myfile.php
anotherC.php
a/
b.php
c.php
The code inside myfile.php is:
<?php
include_once("a/b.php");
?>
The code inside b.php is:
<?php
include_once("c.php");
?>
And finally inside c.php:
<?php
echo "hello i'm C.php";
?>
So, when I call www/myfile.php I get output:
hello i'm C.php
These works fine. But let me change b.php to
<?php
include_once("../anotherC.php"); //or include_once("./c.php"); (it won't work too)
?>
Now, when I call www/myfile.php, i get Error:
Warning: include_once(../anotherC.php): failed to open stream: No such
file or directory in /home/hasib/Desktop/www/a/b.php on line 2
Warning: include_once(): Failed opening '../anotherC.php' for
inclusion (include_path='.:/usr/share/php:/usr/share/pear') in
/home/hasib/Desktop/www/a/b.php on line 2
Now my question is, why The include_once("c.php"); worked perfectly??
the document:
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.
If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether. For example, if a filename begins with ../, the parser will look in the parent directory to find the requested file.
the 'calling script' in your example is b.php , obviously it's directoy is '/www/a/'.
you can use getcwd() to get the 'current directory', either in myfile.php or b.php ,it will return '/www/'
so when include_once("c.php"); it first look up c.php in calling script's directory,that is /www/a/ , and get c.php successfully.
when include_once("../anotherC.php"); , it only look up anotherC.php in relative path to current directory, current directory is /www/ , so it look up anotherC.php in / , /anotherC.php doesn't exists and throw warning.
Includes with relative paths are always done relative to the MAIN script. include() operates essentially the same way as if you'd cut 'n pasted the included data directly into the main script. So when your sub-includes are performed, they're using the working directory of your myFile.php script, NOT the working directory of b.php or c.php.
Your sub-scripts would need to have an absolute path in their icnldues, or at least some kind of "where the heck am I" determination code, e.g. include(__FILE__ . 'c.php')
The only reason I can think of for this working is that you have /www/a in your include_path. This means that include_once("c.php") would first look for /www/c.php (since that's the current working directory), then look for /www/a/c.php which would be found and work.
However, include_once("./c.php") explicitly states to look in the current working directory only, and of course since the file is not there, it won't work.

what am i doing wrong in these php scripts?

Here is config.php
<?php
define("DB_SERVER","localhost");
define("DB_NAME","photo_galley");
define("DB_USER_NAME","root");
define("DB_PASSWORD","");
echo DB_SERVER."config file<br>";
?>
Here is classes.php
<?php
var_dump(include_once("config.php"));
echo DB_SERVER."class file<br/>";
?>
<?php
class MySQLDatabase{...
and here comes third file temp.php
<?php
include_once("includes/classes.php");
echo DB_SERVER." tem.php <br/>";
?>
both classes.php and config.php are in includes folder, includes folder is in photo_gallery folder , temp.php is in photo_gallery folder
how it looks like when i open classes.php in browser.
it shows thing as i thought. First show DB_SERVER value from config.php file then from classes.php file
But when i include classes.php file in any other file like in temp.php as shown in third piece of code it gives something that i didn't understand
here is it
I didn't understand output.
I think it's output should be same as that of classes.php with one more line showing DB_SERVER value from temp.php.
Would you please tell me why these constants are shown as undefined when i open temp.php in browser?
if include function in line is successful as shown by int(1) then why not it show DB_SERVER value from config.php?
You include config.php from wrong location in temp.php. Remove the path. Also you should use require_once rather than include_once as config.php is crucial, so lack of it should stop the script.
In temp.php your config.php file path is wrong. Thats why you got the undefined constant.
config.php file inside the includes directory. But your temp.php file outside the includes directory.
in classes.php, You can use $_SERVER['DOCUMENT_ROOT'] add full path in such way you can access the same in all files.
Your scripts are fine. You just have a problem with your server configuration.
They're working correctly in mine:
When you include classes.php relative path to config.php is includes/config.php.
<?php
include_once("includes/config.php");
class MySQLDatabase{...
so we can say that when we use require include function it just copies code from file mentioned to file from which this function called. so when i call config from classes file it works fine. But when i call classes from temp it just copies code from there but for temp file config file location is different so it doesn't work. Am i correct Mr. Developers...

file_get_contents to url on the same server

I have two files on my server.
File a.php:
<?php
die('this is my text');
?>
File b.php:
<?php
file_get_contents('http://mysite.pl/a.php');
?>
But it's not working... I can't use file_get_contents, when the files are located on the same server, I don't know why.
PHP Info:
allow_url_fopen: ON
allow_url_include: OFF
When I try use the code from file b.php on difficult server - it working... ;/
You could try using 127.0.0.1, however it won't work on a VirtualHost.
You can try the relative path.
If a.php and b.php are in the same directory, do:
// b.php (If a.php is in the same directory)
file_get_contents('./a.php');
If a.php is in the upper directory:
// b.php (If a.php is in an upper directory)
file_get_contents('../a.php');
If a.php is in the root directory:
// b.php (If a.php is in the root directory)
file_get_contents('/a.php');

PHP will include a file relative to a calling script, but not if the include path contains "../"

From what I gather from PHP's documentation and from other posts here, PHP's include (and include_once) do the following:
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
I have the following structure in a given directory:
index.php
/dirA (contains a.php and b.php)
/dirB (contains c.php)
From index.php include_once "dirA/a.php"
Here's what works from within a.php:
include_once "b.php"
include_once "dirB/c.php"
Here's what DOESN"T work from within a.php:
include_once "b.php"
include_once "../dirB/c.php"
The curious thing to me is that b.php is included relative to the "calling script's own directory" but c.php is only considered relative to the current working directory (which is the dir containing index.php). This seems to be a slight inconsistency to me. PHP will include a file relative to a calling script, but not if the include path contains ../ - why? Why won't the ../ parent directory directive work relative to the calling script but it will relative to the current working directory? (note: I tested it relative to the cwd but didn't include that file in my example above just to keep it cleaner. It worked just fine)
Can anyone shed some light as to why this is? Should it work this way, or is this a bug?
PHP's a bit odd in how it looks for files. If you include a file whose name starts with a slash or a dot, PHP ignores the include_path entirely. If a dot, it assumes the name is relative to the script that kicked off everything (ie: the one the web server decided to run).
If you want to specify a path relative to the included script and not the startup one, what you really want is an absolute include that specifies the full name of the file. That's easy to do with the __FILE__ and __DIR__ constants, which reflect the name and directory of the currently running script.
include __DIR__ . '/../dirB/c.php';
If you like, you can also set the include_path config setting to include the root of the app, and just specify all filenames relative to that.
It is because you have first included the dirA/a.php to index.php , so from now on the index.php is your base file from which all includes are taking place. And therefore if you include c.php from a.php it is like you do it from index.php
And that's why you are getting wrong results if you specify one level up with "../" . It searches one level above index.php and it finds nothing.

Categories