Why does setting a global root URL fail with PHP require_once? - php

I have created a file called init.php with the following code (which is included at the top of every page)
<?php
define('APP_ROOT', 'https://example.com/myapp');
?>
I can successfully echo APP_ROOT in a traditional link, even for sub-folders, as follows
linktext
What I cannot do is use the constant with PHP Require, for neither root files or files in sub-folders, as follows
<?php require_once(APP_ROOT . '/test.php') ?>
It returns the following error message:
Fatal error: require_once(): Failed opening required 'https://example.com/myapp/test.php' (include_path='.:/usr/local/php56/pear') in...
Is it even possible to use a constant with require or include statements? If so, would appreciate any direction

If your code is running on multiple servers with different environments (locations from where your scripts run) the following idea may be useful to you:
Do not give absolute path to include files on your server.
Dynamically calculate the full path (absolute path)
Hints:
Use a combination of dirname(FILE) and subsequent calls to itself until you reach to the home of your '/index.php'. Then, attach this variable (that contains the path) to your included files.
One typical example is:
<?php
define('__ROOT__', dirname(dirname(__FILE__)));
require_once(__ROOT__.'/config.php');
?>
https://www.php.net/manual/en/function.require-once.php

Related

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.

php require not working after load() method to refresh a div

I have inside my div a php require to
require('inc/coreturni/list.php');
that requires again a db connection
require('inc/connect.inc.php');
and they both work when I load the page.
but if I try to refresh the div, by refreshing the first include file after a click event, with jquery load()
I got the following path error:
Warning: require(inc/connect.inc.php): failed to open stream: No such file or directory in C:\xampp\htdocs\taximat\inc\coreturni\list.inc.php on line 2
Fatal error: require(): Failed opening required 'inc/connect.inc.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\taximat\inc\coreturni\list.inc.php on line 2
why the path should be different? how could i fix it?
Your error explains it all:
Warning: require(inc/connect.inc.php): failed to open stream: No such
file or directory in
C:\xampp\htdocs\taximat\inc\coreturni\list.inc.php on line 2
Fatal error: require(): Failed opening required 'inc/connect.inc.php'
(include_path='.;C:\xampp\php\PEAR') in
C:\xampp\htdocs\taximat\inc\coreturni\list.inc.php on line 2
Notice how it says it can’t find inc/connect.inc.php in this directory:
C:\xampp\htdocs\taximat\inc\coreturni
It’s because your require statements are referring to relative paths. So when the file list.inc.php is loaded, the require is assuming that inc/connect.inc.php is located in C:\xampp\htdocs\taximat\inc\coreturni. Which is why it is failing.
You should set a base path in your app like so. Just a note that I am unclear on forward-slash or back-slash syntax in a case like this since I work mainly on Mac & Unix systems and the error shows windows paths, but the PHP is showing Unix paths.
$BASE_PATH='/xampp/htdocs/taximat/inc/coreturni/';
And the require all files like this:
require($BASE_PATH . 'inc/coreturni/list.php');
And like this:
require($BASE_PATH . 'inc/connect.inc.php');
That way no matter where the files are called from, the require will use an absolute path to the file. And since $BASE_PATH is a one-time variable you set you can just set it in your main config file and not worry about it. To make the code portable, just change $BASE_PATH based on system setups.
When the page is displayed for the first time, your paths are like this:
page.php
inc/
coreturni/
list.php
connect.php
In other words, all require statements will be relative as seen from page.php.
However, when you request list.php directly using AJAX, it looks more like this:
list.php
../
connect.php
Now, the require should have been for ../connect.php.
Solution
One way to solve this is by calculating the absolute path based on the file currently being processed (i.e. list.php) like this:
require dirname(__DIR__) . '/connect.php';
The dirname(__DIR__) construct will always yield the directory on your file system that's one higher up than the current script is in.

Using includes in php

I have a file that is called header (the header of my site).. I use that file in all my site. The problem is that it has this include in it:
include_once("../untitled/sanitize_string.php");
which means that a mistake may be thrown, depending on who calls the header file.
I have directories, subdirectories and subdirectories to the subdirectories.. is there a simple way to prevent this from happening.. Instead of taking the satize string include and placing it on every page and not in the header file
Warning: require_once(/untitled/sanitize_string.php) [function.require-once]: failed to open stream: No such file or directory in C:\xampp\htdocs\PoliticalForum\StoredProcedure\User\headerSite.php on line 7
Fatal error: require_once() [function.require]: Failed opening required '/untitled/sanitize_string.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\PoliticalForum\StoredProcedure\User\headerSite.php on line 7
You may consider setting a global include path while using include.
For php 5.3 you can do:
include_once(__DIR__ . '/../untitled/sanitize_string.php');
where __DIR__ is the directory for the current file
For older versions you can use
include_once(dirname(__FILE__) . '/../untitled/sanitize_string.php');
where __FILE__ is the path for the current file
Lets say you have the following structure:
/app/path/public/header.php
/app/path/public/user/profile.php
/app/path/untitled/sanitize_string.php
If your header.php includes santitize_script.php with a relative path like so:
include_once("../untitled/sanitize_string.php");
the php interpreter will try to include that file RELATIVELY to the current working dir so if you will do a request like http://localhost/header.php it will try to include it from /app/path/public/../untitled/sanitize_string.php and it will work.
But if you will try to do a request like http://localhost/user/profile.php and profile.php includes header.php, than header.php will try to include the file from /app/path/public/user/../untitled/sanitize_string.php and this will not work anymore. (/app/path/public/user beeing the current working dir now)
That's why is a good practice to use absolute paths when including files. When used in header.php, the __DIR__ and __FILE__ constants will always have the same values: /app/path/public and /app/path/public/header.php respectively no matter where header.php will be used thereafter
Use absolute path...
include_once('/home/you/www/include.php');
Use absolute path as yes123 said.
include_once(dirname(__FILE__)."/../untitled/sanitize_string.php");
You're going to have to use absolute paths here, as opposed to relative. I often set up some constants to represent important directories, using the old Server vars. Like so:
define('MY_DIR',$_SERVER['DOCUMENT_ROOT'].'/path/to/yer/dir');
Then, modify your include statement:
include_once(MY_DIR.'/your_file.php');

PHP is including relative to the URL path and not the file path, how do you change this?

I have a PHP file /a/b/file.php with the line
require("../connect.php");
In connect.php there is a line
require("../config.inc.php");
This all works fine on my local server. There are a bunch of files using connect.php and they all work fine too.
However on the hosting site /a/b/file.php throws an error:
Fatal error: require() [function.require]: Failed opening required
'../config.inc.php' (include_path='.:/usr/local/php5/lib/php') in
/******/connect.php on line 3
I suspect that even though connect.php is in another folder, it's looking for it relative to /a/b. Is there a php.ini setting to change this?
Why dont you use something like:
require( dirname(__FILE__).DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR."connect.php");
This way you will avoid problems like when you develop an app on a Unix-Like system and deploy it on a Windows systems, or viceversa.
I don't know if there's a php.ini setting, but usually I use $_SERVER['DOCUMENT_ROOT'] for my included files.
require $_SERVER['DOCUMENT_ROOT']."/path/relative/to/document_root/file.php";
There are some cases where a relative path is better, but most of the time the files you want to include will stay in the same dir.
Usually I personally make a file called global.php (which is in the root directory of the project) where I define() a constant, include libs and so on.
<?php
// ...
define('APP_INCLUDE_DIR', dirname(__FILE__) .'/');
// ...
?>
Afterwards I include that file in all other files located in the same directory (e.g. index.php with require('global.php'). Now that everything is executed at that directory level you can use the constant APP_INCLUDE_DIR in every file which gets included.
<?php
require('global.php');
// ...
require_once(APP_INCLUDE_DIR .'a/b/c/connect.php');
?>
And in a/b/c/connect.php you could write for example
<?php
// ...
require_once(APP_INCLUDE_DIR .'a/b/config.inc.php');
?>
Check your include_path in your PHP.ini file.
http://php.net/manual/en/function.set-include-path.php
For example, on my local server (XAMPP) it looks like this: `include_path .;C:\xampp\php\PEAR
You can do a phpinfo() to find out also.

How do you know the correct path to use in a PHP require_once() statement

As many do I have a config.php file in the root of a web app that I want to include in almost every other php file. So most of them have a line like:
require_once("config.php");
or sometimes
require_once("../config.php");
or even
require_once("../../config.php");
But I never get it right the first time. I can't figure out what php is going to consider to be the current working directory when reading one of these files. It is apparently not the directory where the file containing the require_once() call is made because I can have two files in the same directory that have different paths for the config.php.
How I have a situation where one path is correct for refreshing the page but an ajax can that updates part of the page requires a different path to the config.php in the require_once() statement;
What's the secret? From where is that path evaluated?
Shoot, I was afraid this wouldn't be a common problem - This is occurring under apache 2.2.8 and PHP 5.2.6 running on windows.
The current working directory for PHP is the directory in which the called script file is located. If your files looked like this:
/A
foo.php
tar.php
B/
bar.php
If you call foo.php (ex: http://example.com/foo.php), the working directory will be /A/. If you call bar.php (ex: http://example.com/B/bar.php), the working directory will be /A/B/.
There is where it gets tricky. Let us say that foo.php is such:
<?php
require_once( 'B/bar.php' );
?>
And bar.php is:
<?php
require_once( 'tar.php');
?>
If we call foo.php, then bar.php will successfully call tar.php because tar.php and foo.php are in the same directory which happens to be the working directory. If you instead call bar.php, it will fail.
Generally you will see either in all files:
require_once( realpath( dirname( __FILE__ ) ).'/../../path/to/file.php' );
or with the config file:
// config file
define( "APP_ROOT", realpath( dirname( __FILE__ ) ).'/' );
with the rest of the files using:
require_once( APP_ROOT.'../../path/to/file.php' );
I like to do this:
require_once(dirname(__FILE__)."/../_include/header.inc");
That way your paths can always be relative to the current file location.
I use the dirname(__FILE__) thing like bobwienholt most the time, but what it could pay to do is have a base entry point that loads all your other code that defines a constant refereing to the root of the project, ie
define("ROOT",dirname(__FILE__).'/' );
and then later all you need to know is where the path is relative to root, ie:
require(ROOT . "/lib/tool/error.php");
note,
you should REALLY avoid paths with "../" at the start of them, they are not relative to the file, but relative to where you ARE and this creates broken-ass code.
cd foo
php bar/baz.php
-> some error saying it cant find the file
cd bar
php baz.php
-> suddenly working.
Important
If you use "../" notation, it takes complete ignorance of the PHP Include Path, And ONLY considers where the person whom is running it is.
I include this code at the top of every page:
//get basic page variables
$self=$_SERVER['PHP_SELF'];
$thispath=dirname($_SERVER['PHP_SELF']);
$sitebasepath=$_SERVER['DOCUMENT_ROOT'];
//include the global settings, variables and includes
include_once("$sitebasepath/globals/global.include.php");
Include and require both take either a relative path or the full rooted path. I prefer working with the full path and make all my references like the inlcude statement above. This allows me to enter a general variable $sitebasepath that handles account specific information that may change from machine to machine and then simply type the path from the webroot, ie. /globals/whatever_file.php
I also use the $self variable in forms that may call themselves to handle data input.
Hope that helps.
If you have sufficient access rights, try to modify PHP's include_path setting for the whole site. If you cannot do that, you'll either have to route every request through the same PHP script (eg. using Apache mod_rewrite) or you'll have to use an "initialization" script that sets up the include_path:
$includeDir = realpath(dirname(__FILE__) . '/include');
ini_set('include_path', $includeDir . PATH_SEPARATOR . ini_get('include_path'));
After that file is included, use paths relative to the include directory:
require_once '../init.php'; // The init-script
require_once 'MyFile.php'; // Includes /include/MyFile.php
Since require and require_once are very similar to include and include_once, all the documentation is posted under the "include" functions doc area on php.net From that page
Files for including are first looked
for in each include_path entry
relative to the current working
directory, and then in the directory
of current script. E.g. if your
include_path is libraries, current
working directory is /www/, you
included include/a.php and there is
include "b.php" in that file, b.php
is first looked in /www/libraries/
and then in /www/include/. If filename
begins with ./ or ../, it is looked
only in the current working directory.
Further, you can find all the current include paths by doing a "php -i" from the command line. You can edit the include path in your php.ini file, and also via ini_set(). You can also run the php_info() function in your page to get a printout of your env vars if the CLI is inconvenient.
The only place I've seen the path evaluated from is the file that you are currently editing. I've never had any problems with it, but if you are, you might want to provide more information (PHP version, OS, etc).
The path of the PHP file requested in the original GET or POST is essentially the 'working directory' of that script. Any "included" or "required" scripts will inherit that as their working directory as well.
I will either use absolute paths in require statements or modify PHP's include_path to include any path in my app I may want to use to save me the extra typing. You'll find that in php.ini.
include_path = ".:/list/of/paths/:/another/path/:/and/another/one"
I don't know if it'll help you out in this particular instance but the magical constants like FILE and DIR can come in handy if you ever need to know the path a particular file is running in.
http://us2.php.net/manual/en/language.constants.predefined.php
Take a look at the function getcwd. http://us2.php.net/getcwd

Categories