dirname(__FILE__) adds path after my domain - php

Here's my problem using the PHP function dirname()
Let me first explain, I'm working on a website where I defined a constant as follow :
define('ROOT', dirname(__FILE__));
That worked well on a shared hosting, but I had to move the website on a dedicated server and now some files I try to call with an absolute link return 404. When I look what path they use, something like this appears :
http://myIp/var/www/myWebsite/[...]/image.jpg
What happens is that, my 'ROOT' constant is '/var/www/myWebsite' but in place of 'Replacing' my domain, it's added at the end of it. Which makes no sense since my Apache VirtualHost sends all requests towards 'myIp' to the local folder '/var/www/myWebsite'.
I don't know if the mistake is either from my PHP code, or my Apache VirtualHost.
Thank you for your help, I'm sure it's something stupid but I can't figure what I did wrong :)

I think you are confusing server paths with site paths.
You would not want to use dirname to give you a path for a web asset.
What you could do if you really want to do it this way is to remove the path to your web root.
This might work:
define('ROOT', str_replace('/var/www/myWebsite/', '/', dirname(__FILE__)));

Related

Why the path beginning with '/' points to 'C:/'?

I have created a site in localhost in the path C:/xampp/htdocs/seintian.altervista.org and then I hosted it in a hosting platform (Altervista).
After some months of programming in that directory I changed the root directory of the site in localhost to, simply, C:/xampp/htdocs because in that way I thought that I would have been able to run the site by searching http://localhost/ and, also, to use the paths /sub/dir/of/the/site instead of the relative ones like ../sub/dir/of/the/site, etc.
However, they somehow point to the path C:/ instead of C:/xampp/htdocs that is the DOCUMENT_ROOT of the Apache site (the local hosting is powered by XAMPP).
Plus, I tried to upload the server folder to Altervista, to see if there worked, but - and you can check by yourselves here - also there it didn't work, responding with a "file or directory not found at [...]" error.
Is it normal that /path/to/file points to C:/ even if the DOCUMENT_ROOT constant is set to C:/xampp/htdocs? And, in any case, how can I make possible that paths like /sub/dir/of/the/site point to the DOCUMENT_ROOT, how expected?
PS: just to say, some paths in link elements in the head section of the page, point correctly to the right path, for example the assets of the page situated in C:/xampp/htdocs/assets. how is it possible? Does PHP just hate me? :'(
Thanks in advance <3
/... points to default storage, so in your case it's C:.
While links in webpage /... links to root directory of http server (do not mix directory path with URL path, they are not the same)
So these are pointing to same location, but has different meaning:
file_get_contents('/etc/dir/xampp/htdocs/assets/images/a.js');
<html>
<head>
<script src="/assets/images/a.js"></script>
I personally suggest to make your site portable by appending __DIR__ to all paths that are used in PHP:
// C:/xampp/htdocs/index.php
ROOT_DIR = __DIR__;
...
file_get_contents(ROOT_DIR . '/assets/images/a.js');

Is it a good idea to use $_SERVER['DOCUMENT_ROOT'] in includes?

Is this, for example, a good idea?
require_once($_SERVER['DOCUMENT_ROOT'].'/include.php');
If you have two virtual hosts on the same server, one for live and one for development, with different Apache DocumentRoots, this would avoid having to include absolute paths when the source of the include is unknown, and may be in any directory.
(Note: file paths in the following section are relative to the web root. They would in fact be like /var/www/app/core/init.php, where /var/www/app is the web root)
For instance: I have an /core/init.php which is called using relative paths from places all over the website (/file.php, /dir/file.php or /dir/dir/file.php).
This init.php then includes several function pages, in the fund directory, a subdir of /core (as in /core/func/userfunctions.php).
So, in init.php, I can use the $_SERVER method, because it breaks if I use a relative path and try to call functions from a page like /dir/file.php.
I can't see any problem with it, but in general what could go wrong?
I've seen cases where $_SERVER['DOCUMENT_ROOT'] is not set or is not what you would expect (i.e. not set in CLI or old IIS, or invalid in certain CGI setups).
For that reason you can use dirname(__FILE__) to obtain the path of the script that line is called in. You can then reference relative paths from there e.g.
include dirname(__FILE__) . '/../../other/file.php';
I go with the above method when the directory structure of the files is known and is not subject to change.
If DOCUMENT_ROOT is not available, the following is a suitable replacement:
substr($_SERVER['SCRIPT_FILENAME'], 0, -strlen($_SERVER['SCRIPT_NAME']));
You don't need to do this. PHP looks for the included file in the document root by default.
You can use set_include_path($new_include_path) to change this behaviour, or edit include_path in the php config file.
Also, from http://php.net/manual/en/reserved.variables.server.php:
'DOCUMENT_ROOT'
The document root directory under which the current script is executing, as defined in the server's configuration file.
For example, if you use URL rewriting, you will be very happy when you find out that the includes in your /there/are/so/many/paths/in/the/url/of/this/ page are still working!

php include vs library; correct path

I have been trying to research what is better to use in order to include repetitive parts of the website - php include function or library(provided in Dreamweaver).
Or maybe there are other - better ways to achieve the same result?
At the moment I use php include and absolute paths. I downloaded the website from the server but it seems that the paths that work on the server don't work on my localhost.
What would be the correct and the best way to write paths in order to make them work on both servers without having to re-write the code?
Thanks
You can call at the start of your script the set_include_path() command and specify relative paths to your libraries
http://www.php.net/set_include_path
Since dream weaver uses library, that's probably wrong ;)
If you want to be sure the code is only included once you might use require_once instead.
Try relative paths instead of absolute
Also an easy way to solve this problem is to define a constant from within the root, normally within your index.php file.
/**Path Environment**/
$root=pathinfo($_SERVER['SCRIPT_FILENAME']);
define ('BASE_FOLDER', basename($root['dirname']));
define ('SITE_ROOT', realpath(dirname(__FILE__)));
define ('SITE_URL', 'http://'.$_SERVER['HTTP_HOST'].'/'.BASE_FOLDER);
Then you can use, SITE_URL and SITE_ROOT throughout your script knowing its the correct path to your web root.
So your old includes look like:
include('/srv/www/somesite.com/public_html/somefile.php');
and your new includes will look like include(SITE_ROOT.'/somefile.php'); then when developing on windows the path will change accordingly.
Put
include_path = ".:/your/absolute/path"
in your php.ini, both Server environment and localhost.
Then you can access the include path file at anywhere of the codes.

DOCUMENT_ROOT is not complete, missing domain folder

I have searched many threads so far but cant seem to find a solution. Inside one of my php scripts I am trying to get a server document root but the value I get is not complete, its simply missing the domain folder. I believe it is due to sharing hosting or smth else.
Here is the current way I am using:
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
and the path I get is like:
/home/content/01/0151247/html
although I know it should be like:
/home/content/01/0151247/html/mydomain
I know as I compared it with SCRIPT_NAME and I see the mydomain there in the path.
Hope someone could direct me.
Thank you and sorry for probably asking another thousand time same question over community, I really tried things around from here, nothing helps me so far.
UPDATE
unfortunately I cant not simply use my index file with DIR as it is a wordpress setup and I am working on a separate folder where I am including some wordpress functionality but for that I need a document_root. If that would help.
UPDATE
apparantly the following way resolved my case, maybe it will help someone one day:
realpath($_SERVER["SUBDOMAIN_DOCUMENT_ROOT"]);
basically because of the server setup and domain configured as a subdomain.
Thanks to all who participated.
Prior to PHP 5.3 you can put a file in the directory whose path you want and define a constant:
define('ROOT_DIR', dirname( __FILE__ ));
After 5.3 you can just do:
define('ROOT_DIR', __DIR__);
The idea being that this would be in config.php of some sort that is included every time the application runs.
Magic Constants Docs
UPDATE
In the config file, you can just append the DOCUMENT_ROOT variable:
$_SERVER['DOCUMENT_ROOT'] = $_SERVER['DOCUMENT_ROOT'] . '/mydomain';
And that should take care of it for you.
Old Solution
The DOCUMENT_ROOT is an environment variable set by the server. So if this is on shared hosting, you cannot changed. An alternative is to set your own constant to it, so in a config type file that is included on your pages you can do something like:
define('DOCUMENT_ROOT', $_SERVER['DOCUMENT_ROOT'] . '/mydomain');
And then just use that constant in place of $_SERVER['DOCUMENT_ROOT']. The other option is to contact your host and inquire about it, maybe it was an oversight on their part and they will fix it.
EDIT
Probably using the __DIR__ as others have posted about is the better way, as the DOCUMENT_ROOT can be set to different items and at least with the __DIR__ you should get an accurate directory each time.
Personally, to get the root of a folder in PHP, I use this in the my index file:
define('ROOT', dirname(__FILE__)); // __DIR__ will work under PHP 5.3

How to programmatically determine the document root in PHP?

Here's a problem that I've been running into lately - a misconfigured apache on a webhost. This means that all scripts that rely on $_SERVER['DOCUMENT_ROOT'] break. The easiest workaround that I've found is just set the variable in some global include files that is shared, but it's a pain not to forget it. My question is, how do I determine the correct document root programatically?
For example, on one host, the setup is like this:
$_SERVER['DOCUMENT_ROOT'] == '/htdocs'
The real document roots are:
test.example.com -> /data/htdocs/example.com/test
www.example.com -> /data/htdocs/example.com/www
And I'd like a script that's run from www.example.com/blog/ (on the path /data/htdocs/example.com/www/blog) to get the correct value of /data/htdocs/example.com/www.
On another host, the setup is a bit different:
$_SERVER['DOCUMENT_ROOT'] == '/srv'
test.example.com -> /home/virtual_web/example.com/public_html/test
www.example.com -> /home/virtual_web/example.com/public_html/www
Is there any solution to this? Or is the only way simply not to ever rely on $_SERVER['DOCUMENT_ROOT'] and fix all the software that I'm running on my sites? Fixing this on the hosting's side doesn't seem to be an option, I've yet to encounter a host where this is was configured correctly. The best I got was a document root pointing to www.example.com, which was at least inside open_basedir - they used yet another naming scheme, www.example.com would point to /u2/www/example_com/data/www/.
In PHP5 there is the magic constant __FILE__ that contains the absolute path of the file in which it appears. You can use it in combination with dirname to calculate the document root.
You can put a statement like the following one in a config file
define ('DOCUMENT_ROOT', dirname(__FILE__));
this should do the trick
There's no need to modify all scripts.
You can run PHP file before any script is run using auto_prepend_file.
$_SERVER is just an array, you can modify it and set correct $_SERVER['DOCUMENT_ROOT'].
This is one reason why people siphon everything through a bootstrap /index.php using htaccess and/or query strings. You can use the dirname( __FILE__ ) trick noted above and get the public base of your app that way.
If you're too far into it to switch to a single entry point, one thing I've seen people do is have a common header to their script which walks up the directory tree to find a file which is unique to the base dir:
function findAppBase( $dir ) {
if( file_exists( "$dir/unique_file.txt" ) ) {
return $dir;
return findAppBase( dirname( $dir ) );
}
$base = findAppBase( dirname( __FILE__ ) );
That code hasn't been tested, and there might be a slicker way using the vars in $_ENV or $_SERVER that will do what you want...
Based on http://www.helicron.net/php/:
$localpath=getenv("SCRIPT_NAME");
$absolutepath=getenv("SCRIPT_FILENAME");
$_SERVER['DOCUMENT_ROOT']=substr($absolutepath,0,strpos($absolutepath,$localpath));
I had to change the basename/realpath trick because it returned an empty string on my host. Instead, I use SCRIPT_FILENAME. This probably won't work on IIS anymore (but the original scripts that used the $_SERVER variable probably wouldn't either).
PHP should be setting the current directory to the one the script is in, so as long as that's not broken you should be able to figure out the document root using $_SERVER['SCRIPT_FILENAME'] and getcwd(). (I can't remember all the $_SERVER vars off the top of my head, there might be something in phpinfo() that's more useful.)
Why not demand that your webhost configures his servers correctly?
these kind of things tend to linger silently in your code and never get removed (but still active) until someone finally fixes the server. Thén everything will break again.
Or, move your stuff to a host that will work. If this is broken, who knows what you will find next.

Categories