file_get_contents with relative path - php

I have the following directory structure.
/var/www/base/controller/detail.php
/var/www/base/validate/edit.json
/var/www/html
Within /var/www/base/controller/detail.php, how do I use file_get_contents() with a relative path to read /var/www/base/validate/edit.json? I've tried the following:
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('detail.php');
//No error, but I don't want this file and was just testing
$json=file_get_contents('detail.php', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('./validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('../validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('././validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('../../validate/edit.json', FILE_USE_INCLUDE_PATH);
//This works, but I want to use a relative path
$json=file_get_contents(dirname(dirname(__FILE__)).'/validate/edit.json');

Have you tried:
$json = file_get_contents(__DIR__ . '/../validate/edit.json');
__DIR__ is a useful magic constant.
For reasons why, see http://yagudaev.com/posts/resolving-php-relative-path-problem/.
When a PHP file includes another PHP file which itself includes yet another file — all being in separate directories — using relative paths to include them may raise a problem.
PHP will often report that it is unable to find the third file, but why?
Well the answer lies in the fact that when including files in PHP the interpreter tries to find the file in the current working directory.
In other words, if you run the script in a directory called A and you include a script that is found in directory B, then the relative path will be resolved relative to A when executing a script found in directory B.
So, if the script inside directory B includes another file that is in a different directory, the path will still be calculated relative to A not relative to B as you might expect.

try using this
$json = file_get_contents("/path/to/your/file/edit.json", true);
As of PHP 5 the FILE_USE_INCLUDE_PATH constant can be used to trigger include path search. This is not possible if strict typing is enabled since FILE_USE_INCLUDE_PATH is an int. Use TRUE instead.

Of cause there is the possibility to use the include_path parameter. Set this parameter to '1' then a search for the file in the include_path (in php.ini.) will be done. You have to do editing in the php.ini!
When using $json=file_get_contents('detail.php'); a call is done from a php file.
Use file_get_contents('detail.php'); to have the detail.php get executed. the file have to be in the root directory (same as the calling php file in which the file_get_contents() is situated). If detail.php is in a subdirectory i can not see any workaround than using the include_path parameter

You can always try to do the opposite first to find out:
file_put_contents('FINDME', 'smth');
exit();
$json=file_get_contents('detail.php');
...
Then run something like this from your terminal on *nix system (or search for a file named FINDME using GUI on Windows)
find <root-dir-of-the-project> -name 'FINDME'
The command will output something like this:
<root-dir-of-the-project>/<directories>/FINDME
Now you know the root dir (from which the relative path is being taken) for the file where you are attempting to read the other files and you can construct the relative path easily

Related

Warning: require_once(/HTML/Template/ITX.php): failed to open stream: No such file or directory in C:\wamp64\www\mysite\main\login.php on line 13 [duplicate]

I was writing an web app in PHP, when I encountered a strange situation. To illustrate my problem, consider a web app of this structure:
/
index.php
f1/
f1.php
f2/
f2.php
Contents of these files:
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("../f2/f2.php"); ?>
f2.php: blank
now when I try to open index.php in my browser I get this error:
Warning: require_once(../f2/f2.php) [function.require-once]:
failed to open stream: No such file or directory in /var/www/reqtest/f1/f1.php on line 2
Fatal error: require_once() [function.require]:
Failed opening required '../f2/f2.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/reqtest/f1/f1.php on line 2
Is there something obvious I'm missing? how do include paths work in PHP?
Before I asked this question, I attempted to experiment and find out. I set up another test, like so:
/
index.php
f1/
f1.php
f2.php
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("f2.php"); ?>
f2.php: blank
To my surprise (and utter confusion), this worked out fine!
So, what is the secret behind the path resolution?
PS I saw this question, but it still does not answer the second case that I've stated here.
If you include another file, the working directory remains where the including file is.
Your examples are working as intended.
Edit: The second example works because . (actual directory) is in your include path (see your error message).
Edit2:
In your second example, the key point of your interest is this line:
<?php require_once("f2.php"); ?>
At first it will look in the current working dir (/var/www/req_path_test), but does not find f2.php.
As fallback, it will try to find f2.php in your include_path ('.:/usr/share/php:/usr/share/pear'), starting with '.' (which is relative to the actual file, not the including one).
So './f2.php' works and the require does not fail.
When you open index.php, working dir is set to the folder this file resides in. And inside insluded f1.php this working dir does not change.
You can include files by using their absolute paths, relative to the current included file like this:
require_once(dirname(__FILE__).'/../../test/file.php')
But better consider using an autoloader if these files contain classes.
Normaly in you old structure
<?php require_once("f2/f2.php"); ?>
instead of
<?php require_once("../f2/f2.php"); ?>
should work. As far as i know php takes the paths from the initial script
It sounds like your server has the open_basedir setting enabled in the PHP configuration. This makes it impossible to include (and open) files in folders above your in the directory structur (i.e., you can't use ../ to go up in the folder structure).
From the PHP Docs PHP include
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.
If the file path is not given then i.e require_once("f2.php");
1st. The include_path is checked
2nd. The calling scripts own directory is checked
3rd. Finally the current working directory is checked
If file not found then PHP throws warning on file include & fatal error on require
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.
If you include/require your file beginning with . or .. or ./ then PHP's parser will look in the parent directory which is the current working directory i.e require_once("../f2/f2.php"), php will check at the root directory as the calling script index.php is in that directory.
Now You have not defined any include path in your PHP script thus it always falls back to the calling script and then into the current working directory.
// Check your default include path, most likely to be C:\xampp\php\PEAR
echo get_include_path();
// To set include path
set_include_path ( string $new_include_path ) : string
The Current Working Directory is derived from your main calling script index.php.
// The Current Working Directory can be checked
echo getcwd();
In the first Example where the required file "../f2/f2.php" is from f1.php
You code does not work because -
The specified path is ignored by PHP as your filename begins with ../
f1/ the calling script's own directory is ignored as well.
The parser directory looks into the parent directory to find the requested file. The current working directory is root directory, this is from where you have initiated the working script index.php. The file is not located at this directory, wrong path given.
Thus you get the Fatal Error
In the Second example you have changed the directory & from f1.php you require_once("f2.php").
Your code works because -
This time you require("f2.php") no leading ../ or ./ This time PHP checks the include_path but does find it there, as you haven't defined it and the file does not reside in the default preset include_path.
This time the calling script f1.php's directory is f1/. and you require file ("f2.php") is located at this directory. PHP This time checks the file in this directory and finds it.
PHP does not have to check the working directory as the file was found.
Thus Your Code Works Fine!

Cannot reference another php file in another folder [duplicate]

I have the following directory structure.
/var/www/base/controller/detail.php
/var/www/base/validate/edit.json
/var/www/html
Within /var/www/base/controller/detail.php, how do I use file_get_contents() with a relative path to read /var/www/base/validate/edit.json? I've tried the following:
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('detail.php');
//No error, but I don't want this file and was just testing
$json=file_get_contents('detail.php', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('./validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('../validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('././validate/edit.json', FILE_USE_INCLUDE_PATH);
//failed to open stream: No such file or directory (error no: 2)
$json=file_get_contents('../../validate/edit.json', FILE_USE_INCLUDE_PATH);
//This works, but I want to use a relative path
$json=file_get_contents(dirname(dirname(__FILE__)).'/validate/edit.json');
Have you tried:
$json = file_get_contents(__DIR__ . '/../validate/edit.json');
__DIR__ is a useful magic constant.
For reasons why, see http://yagudaev.com/posts/resolving-php-relative-path-problem/.
When a PHP file includes another PHP file which itself includes yet another file — all being in separate directories — using relative paths to include them may raise a problem.
PHP will often report that it is unable to find the third file, but why?
Well the answer lies in the fact that when including files in PHP the interpreter tries to find the file in the current working directory.
In other words, if you run the script in a directory called A and you include a script that is found in directory B, then the relative path will be resolved relative to A when executing a script found in directory B.
So, if the script inside directory B includes another file that is in a different directory, the path will still be calculated relative to A not relative to B as you might expect.
try using this
$json = file_get_contents("/path/to/your/file/edit.json", true);
As of PHP 5 the FILE_USE_INCLUDE_PATH constant can be used to trigger include path search. This is not possible if strict typing is enabled since FILE_USE_INCLUDE_PATH is an int. Use TRUE instead.
Of cause there is the possibility to use the include_path parameter. Set this parameter to '1' then a search for the file in the include_path (in php.ini.) will be done. You have to do editing in the php.ini!
When using $json=file_get_contents('detail.php'); a call is done from a php file.
Use file_get_contents('detail.php'); to have the detail.php get executed. the file have to be in the root directory (same as the calling php file in which the file_get_contents() is situated). If detail.php is in a subdirectory i can not see any workaround than using the include_path parameter
You can always try to do the opposite first to find out:
file_put_contents('FINDME', 'smth');
exit();
$json=file_get_contents('detail.php');
...
Then run something like this from your terminal on *nix system (or search for a file named FINDME using GUI on Windows)
find <root-dir-of-the-project> -name 'FINDME'
The command will output something like this:
<root-dir-of-the-project>/<directories>/FINDME
Now you know the root dir (from which the relative path is being taken) for the file where you are attempting to read the other files and you can construct the relative path easily

Even if the csv file is in the directory, it returns PHP: failed to open stream: No such file or directory.

May I ask a dumb question? I have already checked the answers for the same error such as. PHP - Failed to open stream : No such file or directory. and couple of others.
However, this one seems more elmentary problem. I am using XAMPP and I have checked the the property of csv file and it says the location. C:\xampp\htdocs
Then, I checked http://localhost/Untitled-2.php and it reutrns:
Warning: file(Book 1.csv 1): failed to open stream: No such file or directory in C:\xampp\htdocs\Untitled-2.php on line 2
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\Untitled-2.php on line 3
Why am I getting these error? My code is the following script:
<?php
$read = file("Book 1.csv 1");
foreach($read as $line){
echo $line .",";
}
?>
So, I think you have a problem with relative and absolute paths.
file("foo.bar") will try to open the file foo.bar relative to your current path. If you ran your php script from the command line, it will try to open the file in the directory you were in when you ran php.
So if you have the following directory structure:
/foo/
/foo/test.php
/foo/bar.csv
/bar.txt
And you are running php from your root directory:
/ $ php /foo/test.php
The working directory of your file will be /, even though the php file itself was in /foo. So if you do
file('bar.csv');
What php will try to open is in fact /bar.csv which doesn't exist.
Please note that what will be the relative working directory of your script can greatly differ in how your script were ran. If it is running from php-fpm mode, it will depend on your config.
To test what your current working directory is, do
echo getcwd();
And then you can list the contents of your working directory with
$files = glob(getcwd() . DIRECTORY_SEPARATOR, GLOB_NOSORT);
var_dump($files);
Or you could do something similar with readdir
All in all, I think you should try to avoid using relative file paths, as it can open up all sorts of problems. If possible, try to use absolute paths instead, like:
file('/var/www/file.csv');
I'm assuming your filename is Book 1.csv because it makes more sense. Your code might have a typo, as the file source is currently Book 1.csv 1 and this could be the cause of your problem.
Try this:
$read = file("Book 1.csv");

Why do I get a Warning and a Fatal error when I use ../?

When I use ../mysqlConnect.php I get the following messages.
Warning: require_once(../mysqlConnect.php) [function.require-once]:
failed to open stream: No such file or directory in /home/content/etc...
Fatal error: require_once() [function.require]: Failed opening required
'../mysqlConnect.php' (include_path='.:/usr/local/php5/lib/php') in /home/content/etc...
When I use the directory name - mydir/mysqlConnect.php - everything works fine.
require_once('../mysqlConnect.php') asks PHP to look in the directory above the one your script is currently in for mysqlConnect.php.
Since your connection file appears to be in a mydir directory, require_once('mydir/mysqlConnect.php') works because it looks in that directory, which is contained by the one it's currently in.
Visual representation (assuming script.php is your script including that file):
dir/
subdir/ # PHP looks here for ../mysqlConnect.php
script.php
mydir/ # PHP looks here for mydir/mysqlConnect.php
mysqlConnect.php
Require is relative to the invoced script, not the script you call require() in. Use something like this to have an absolute path:
require(dirname(__FILE__) . '/../mysqlConnect.php');
In PHP 5 you can also use DIR.
because it doesn't find your file then. to give a more specific answer I need to see you file-/folder-structure
That's because you are not specifying the correct include path. ../ refers to parent directory. ../../ goes two directories back, ../../../ goes three of them back. If the mysqlConnect.php file is present in the same folder as your script, you don't need to specify ../ in the include.
Make sure that you specify the correct path. You can easily check whether or not you are specifying correct path like:
if (file_exists('../mysqlConnect.php'))
{
echo 'Iam specifying the correct path !!';
}
else
{
echo 'Well, I am not :(';
}

How does include path resolution work in require_once?

I was writing an web app in PHP, when I encountered a strange situation. To illustrate my problem, consider a web app of this structure:
/
index.php
f1/
f1.php
f2/
f2.php
Contents of these files:
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("../f2/f2.php"); ?>
f2.php: blank
now when I try to open index.php in my browser I get this error:
Warning: require_once(../f2/f2.php) [function.require-once]:
failed to open stream: No such file or directory in /var/www/reqtest/f1/f1.php on line 2
Fatal error: require_once() [function.require]:
Failed opening required '../f2/f2.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/reqtest/f1/f1.php on line 2
Is there something obvious I'm missing? how do include paths work in PHP?
Before I asked this question, I attempted to experiment and find out. I set up another test, like so:
/
index.php
f1/
f1.php
f2.php
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("f2.php"); ?>
f2.php: blank
To my surprise (and utter confusion), this worked out fine!
So, what is the secret behind the path resolution?
PS I saw this question, but it still does not answer the second case that I've stated here.
If you include another file, the working directory remains where the including file is.
Your examples are working as intended.
Edit: The second example works because . (actual directory) is in your include path (see your error message).
Edit2:
In your second example, the key point of your interest is this line:
<?php require_once("f2.php"); ?>
At first it will look in the current working dir (/var/www/req_path_test), but does not find f2.php.
As fallback, it will try to find f2.php in your include_path ('.:/usr/share/php:/usr/share/pear'), starting with '.' (which is relative to the actual file, not the including one).
So './f2.php' works and the require does not fail.
When you open index.php, working dir is set to the folder this file resides in. And inside insluded f1.php this working dir does not change.
You can include files by using their absolute paths, relative to the current included file like this:
require_once(dirname(__FILE__).'/../../test/file.php')
But better consider using an autoloader if these files contain classes.
Normaly in you old structure
<?php require_once("f2/f2.php"); ?>
instead of
<?php require_once("../f2/f2.php"); ?>
should work. As far as i know php takes the paths from the initial script
It sounds like your server has the open_basedir setting enabled in the PHP configuration. This makes it impossible to include (and open) files in folders above your in the directory structur (i.e., you can't use ../ to go up in the folder structure).
From the PHP Docs PHP include
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.
If the file path is not given then i.e require_once("f2.php");
1st. The include_path is checked
2nd. The calling scripts own directory is checked
3rd. Finally the current working directory is checked
If file not found then PHP throws warning on file include & fatal error on require
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.
If you include/require your file beginning with . or .. or ./ then PHP's parser will look in the parent directory which is the current working directory i.e require_once("../f2/f2.php"), php will check at the root directory as the calling script index.php is in that directory.
Now You have not defined any include path in your PHP script thus it always falls back to the calling script and then into the current working directory.
// Check your default include path, most likely to be C:\xampp\php\PEAR
echo get_include_path();
// To set include path
set_include_path ( string $new_include_path ) : string
The Current Working Directory is derived from your main calling script index.php.
// The Current Working Directory can be checked
echo getcwd();
In the first Example where the required file "../f2/f2.php" is from f1.php
You code does not work because -
The specified path is ignored by PHP as your filename begins with ../
f1/ the calling script's own directory is ignored as well.
The parser directory looks into the parent directory to find the requested file. The current working directory is root directory, this is from where you have initiated the working script index.php. The file is not located at this directory, wrong path given.
Thus you get the Fatal Error
In the Second example you have changed the directory & from f1.php you require_once("f2.php").
Your code works because -
This time you require("f2.php") no leading ../ or ./ This time PHP checks the include_path but does find it there, as you haven't defined it and the file does not reside in the default preset include_path.
This time the calling script f1.php's directory is f1/. and you require file ("f2.php") is located at this directory. PHP This time checks the file in this directory and finds it.
PHP does not have to check the working directory as the file was found.
Thus Your Code Works Fine!

Categories