DOCUMENT_ROOT is not complete, missing domain folder - php

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

Related

Having issues with getting root path directory from different folders

I am trying to connect a certain header file for different files in different folders. The problem is when having the same file included in for example /backend it will be easily called directly (as the index is also in /backend) but when calling it from backend/pages it doesnt recall the link structure anymore resulting in a deadlink.
I have tried every possible thing with ../ and different header files but that is a no go. Trying to find a solution such as the url below comes really close but yet I cannot seem to figure it.
Root path variable in a PHP project
What would be the best way to include the root automatically in an include or require for example.
If you're using a front controller (like an index.php file) that is starting and executing your entire application you can just set a constant there like define('APP_ROOT', __DIR__); and that'll set the root to be your front controller.
You can access your header file from anywhere then by doing APP_ROOT . "/includes/header.php"
If you are not using a front controller, then you can set this in each file. So for backend/pages it'd be something like ./../includes/header.php. or better still, use $_SERVER['DOCUMENT_ROOT'] to get the root of your application as provided by your web server vhosts config. (Apache of NGINX most likely)
$_SERVER['DOCUMENT_ROOT'] . "/app/backend/includes/header.php" for example.
What would be the best way to include the root automatically in an include or require for example.
I'm not aware of any method to do that without modifying PHP itself and re-compiling from source, but I could be wrong. Your root path will always be stored in $_SERVER['DOCUMENT_ROOT'].
I think what you might want to look into is autoloading and more specifically PSR-4 and composer.

Bulletproof PHP include from project's root

Okay so I don't know if this is a "can't see the forest for the trees" situation but I'm slowly losing my patience on this.
All I want to do is find a way to include files from the project's root, no matter how nested the file, no matter where it's all hosted.
I obviously can't just do absolute paths like "/includes/file.php".
I can't use $_SERVER['DOCUMENT_ROOT'] because, as far as the servers where I'm hosting it are concerned, that's the wrong path.
I read about creating a config.php file in the root directory and defining the ROOT_DIR there, but that means I have to include that file RELATIVE in every script, which makes things unstable again. (I don't want every include to break because I moved the file somewhere else)
I can't use constants like DIR because it returns the current directory, not the absolute project root.
I tried to set the include path, which doesn't seem to work.
The only "solution" that works for me as of right now: In every file, I define a $root variable and set it to the path that I know is the correct project root.
That can't possibly be the best solution, can it?
There must be an easier way. And the fact that I can't find it drives me crazy.
The root path that works looks something like this:
"/mnt/web10145/dd3/519/5878104319/htdocs/project" (numbers changed)
Using this for includes works just fine. However, calling set_include_path($path) and then including without that path doesn't work.
Please, if anyone knows anything: Every answer is deeply appreciated.
Don't mind pointing out how stupid I am to not have thought about xyz. If it helps me solve the problem it's all good.
Thank you!

dirname(__FILE__) adds path after my domain

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__)));

PHP include path different on different servers

In my site, i have a place that says:
include('../tpls/header_home.php');
and it works. Now i am moving the site to another server, where i get the error:
Warning: include(../tpls/header_home.php) [function.include]: failed to open stream: No such file or directory in /home/usern/public_html/site/tpls/static/home.php on line 4
now if I replace the line with this one, it works:
include('site/tpls/header_home.php');
I could change it, but i don't know how many more places I have of broken paths all around, not only in templates, but files, uploads etc.
I would rather fix the problem generally from a setting or something else I am missing. What do I do?
HINT:
Old working server gives me CWD:
/home/ortho/public_html/site/lib
New server that is problematic gives me CWD:
/home/orthosho/public_html
why?
STRUCTURE:
/home/usern/public_html/site/tpls/static/home.php
/home/usern/public_html/site/tpls/header_home.php
PHP old server: 5.2.17
PHP new server: 5.3.8
maybe that is causing problems?
Well, you basically answered your own question.
Create a settings file where you keep all of these specific paths as variables or otherwise, and include that file wherever you need to reference the paths. That's generally how it works.
settings.inc.php:
$_CONFIG['BASE_DIR'] = "/var/www/yoursite.com/";
some_file.php:
require 'settings.inc.php';
include $_CONFIG['BASE_DIR'] . "some_dependency.php";
I assume you are trying to fix the issue having already made the entire system, without a common settings file, in which case I don't have an answer. You should really centralise things as soon as you start coding to avoid these kinds of issues.
You must have config file, which will have the abosolute path to your site, ofc it will be relative (no need to be hardcoded url) and then use it in all include calls.
Let me explain you, lets say you have a folder in your site called config and in in file called config.php. If you want you could make config class that will hold all your important variables. One of them should be
$ROOT_PATH = str_replace( '\\', '/', dirname( dirname( __FILE__ ) ) ) . '/';
That will be root path relative to your project. Then you can simply call this variable elsewhere when you include something:
require_once $ROOT_PATH . 'blabla/test.php';
Alternative to fix your broken code is to redefine include path with set_include_path()
http://php.net/manual/en/function.set-include-path.php
But for future, learn to code smart :)
Given your new information, the problem is the following:
Old server => ~/public_html/site/lib
New server => ~/public_html
Why? Well, it's because you've set it that way. How do you access the previous website? yourdomain.com/site/, or just yourdomain.com? If it's the first one, then it's bound to be that you've got different web roots.
Now, what you're trying to include is this:
Old server => ~/public_html/site/tpls/...
New server => ~/tpls/
That doesn't quite look right does it?
My guess is that you'd need to alter the document root in httpd.conf in some way.
Sometimes it helps to use dirname so its really relative to the current file. this is what I use if I make cronjobs, and its more "portable" this way
<?php
include dirname(__FILE__)."/../tpls/header_home.php";

How do you developers set your paths for templates?

I thought I would ask in case I could do it a better way.
On my local (WAMP) I have all my website in the www folder. ( C:\wamp\www )
Now currently I do this when i include a file:
require_once("".$_SERVER['DOCUMENT_ROOT']."/lib/config.php");
When I am working on local and upload site to a webhost i want to ensure the paths don't breakI
Could someone please tell me if I should be doing it this way?
I want to ensure maximum compatibility; meaning that paths won't break if I, for example, move site from local to whatever web host I decided to use or if I, for example, move from one host to another.
Maybe there is a more bullet proof way of doing it?
The problem with using $_SERVER['DOCUMENT_ROOT'] is that it will break if you move your PHP scripts up or down a directory level. Instead use this:
require_once(dirname(__FILE__) . "/lib/config.php");
__FILE__ is the absolute path of the script. dirname() removes the last path component (the script filename) so you can append other path components to it, like /lib/config.php or /../../lib/config.php or whatever. This will work everywhere.
PHP 5.3 introduced a shorthand for dirname(__FILE__), called __DIR__, but this doesn't work in <5.3.
You should see Include path. For that set_include_path is useful.
What I usually do, is make 1 config file (which might include others) with a few very basic constants:
define('PROJECT_ROOT', dirname(dirname(__FILE__))); // or dirname(__DIR__) for PHP 5.3
define('PROJECT_WEB', $_SERVER['DOCUMENT_ROOT']);
// etc
Al my other files/includes will be based on those very simple constants. I will never need relative paths and never the include_path, because both PROJECT_ROOT and PROJECT_WEB are 'real'/absolute.
Other useful (?) constants would be PROJECT_LOGIC and/or PROJECT_CONTROLLERS and/or PROJECT_3RD_PARTY etc.
That works fine for including the config file (although i would get rid of the beginning quotes)
require_once( $_SERVER['DOCUMENT_ROOT'] . "/lib/config.php" );
This is really the only way to do it if you are including the config file from a bunch of different directories.
On bigger project id say that "most" developers have a front controller that all scripts are loaded from. This front controller loads the config file and since its the same file always including the config file there's no need for $_SERVER['DOCUMENT_ROOT'].

Categories