>>> How to get root directory in PHP for making include code portable

Hi Guys,

I've just started using includes in PHP and I need some help!  : )

Here's what I'm trying to do.  I have a bit of code which was redundant on many scripts of the site.  These scripts are in many different directories.

I have created an include file which contains the code.  Now I want to create a line of code which I can place into all the scripts which need the include code.  

Ideally it would look something like this:
     include  ( [site root string or equivalent] . "/includes/code.php");

I know I can enter the path in manually but I want this to be portable.

And I know I can use relative paths but that would mean I'd have to count how many folders each script is nested in and probably make mistakes which will cause problems.

What I need is to have one line of code which I can use on all scripts no matter where they are on the site relative to the root directory and which can be portable.

I've been looking for hours and it seems many people have the same problem but nobody has an easy solution. You'd think PHP would have a $_SERVER['rootdir'] variable built in but it doesn't look like that's the case.

Thanks!
John

webgeek154Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Roger BaklundCommented:
Why can't you just use:

 include("/includes/code.php");
0
glcumminsCommented:
In my applications (and in as many major open-source applications as I can think of), the installation directory is always specified in a configuration file. You can set it as a define like this:

define('APPLICATION_DIRECTORY', '/path/to/your/application');

After the define has been created, you can use:

 include  ( APPLICATION_DIRECTORY . "/includes/code.php");

This will require that either a), your user sets the path in the configuration file, or b) you use an installation script that checks the current directory and saves it as the install directory.

Unfortunately, there does not seem to be a "magic" way to make this work. However, using a simple configuration entry does the trick.
0
Roger BaklundCommented:
You probably need $_SERVER["DOCUMENT_ROOT"]...

include($_SERVER["DOCUMENT_ROOT"]."/includes/code.php");
0
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

webgeek154Author Commented:
@cxr
i know abut document root but that will give me the path to the script which is being executed.  Since this include line needs to be the same on different scripts throughout the site in different directories, this doesn't work very well.

@glcummins:
there's no application.  I'm just including bits of code into many pages which are in many different directories.  
0
Roger BaklundCommented:
On my server (MS Vista, Apache 2.2.9, PHP 5.2.6) $_SERVER['DOCUMENT_ROOT'] contains the path to the root of the server, i.e. the folder at "http://domainname/", regardless of what sub-folder my script is in.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
NoiSCommented:
I frequently use this method

ALL my projects have this structure

[root]
   [web] (site_root)
      index.php
      [images]
         some.image.jpg  
   [lib]
      [DAO]
          DataAccessObjects.class.php
      [TO]
         TransferObjects.class.php
    some.class.php
    [templates]
       templates.html
config.file.php


On config.file.php I create a Constant called ROOT_DIR
define('ROOT_DIR',dirname(__FILE__),true);

On index.php (application door) I include config.file.php
  include_once "../config.file.php"; so ROOT_DIR constant will be available

After ROOT_DIR I can use include by ROOT_DIR
include ROOT_DIR ."/lib/DAO/DataAccessObjects.class.php";


Some time I use this function to include files dinamically
 	/**
 	 * Returns all directories and subdirectories for a path
 	 * @param string {path} Path to generate dir list
 	 * @return srray Array with all dirs on the path
 	 */
 	function getDirsRecursively($path){		
		if(!is_dir($path)){
			return array($path);
		}
				
		$retdirs = glob($path . DIRECTORY_SEPARATOR . '*',GLOB_ONLYDIR);
		foreach($retdirs as $dir){
			$retdirs = array_merge($retdirs,self::getDirsRecursively($dir));
		}
		return $retdirs;
 	 }
// Usually I put this code on the config file
$dirs = array_merge(Utils::getDirsRecursively(ROOT_DIR),explode(PATH_SEPARATOR,get_include_path()));
$dirs = array_unique($dirs);
// Adding the current dir to facilitate file inclusion 
// e class loading 
set_include_path(	implode(PATH_SEPARATOR,$dirs) );
 
// This is my Autoload function
 	if(!defined('__autoload')){
		/**
		 * Automatically load a required class file
		 * the file must have the same class name with a .class sufix 
		 * @param string {class_name} 
		 * 
		 */
		function __autoload($class_name) {
	    	try{
			    if(class_exists($class_name)){
			    	return;
			    }	
				
				// Searching for the class file on the application path
				$path = explode(PATH_SEPARATOR,get_include_path());
				foreach($path as $dir){
					if (is_file($dir . DIRECTORY_SEPARATOR . $class_name . '.class.php' )){
						require_once $dir . DIRECTORY_SEPARATOR . $class_name . '.class.php';
						return;
					}
				}
	    	}catch(Exception $e){
	    		trigger_error("Error loading $class_name class .\n\nDetalhes:" . $e->getMessage(),E_USER_ERROR);
	    	}
		}
 	}

Open in new window

0
NoiSCommented:
... continuation
For the dinamic include
function myInclude($filename){
   try{
       if(in_array(filename,get_included_files)){ // already included
           return;
       }   
                                
       // Searching for the file on the application path
      $path = explode(PATH_SEPARATOR,get_include_path());
      foreach($path as $dir){
         if (is_file($dir . DIRECTORY_SEPARATOR . $filename )){
              require_once $dir . DIRECTORY_SEPARATOR . $filename;
              return;
         }
      }
  }catch(Exception $e){
     trigger_error("Error including $filename .\n\nDetails:" . $e->getMessage(),E_USER_ERROR);
   }
 
}
 
// now I can use 
myInclude("file.tobe.include.php");
 
The only restriction. Cannot have files with same names 'cause the behavior will be unespected.

Open in new window

0
webgeek154Author Commented:
@cxr:
Right you are!  I had tried that before but I must have done something wrong because it was giving me different results.  I just tried it again and you are indeed right.  I can't believe I spent so much time on a problem that had such a simple solution : )

This is EXACTLY the solution I needed.

@NoiS:
Your solution is more advanced than I can understand.  I'm sure it's very useful but the $_SERVER['DOCUMENT_ROOT'] variable pointed out by cxr has exactly what I need.

Thanks!
John
0
webgeek154Author Commented:
Thanks!
0
Naveed_ManzoorCommented:
For portability use
if(!isset($_SESSION["$Chk_Server"])){      

      if( stristr($_SERVER['HTTP_HOST'], 'local' ) || (substr($_SERVER['HTTP_HOST'], 0 , 7)  == '192.168')
                  || stristr($_SERVER['HTTP_HOST'], '127.0.0.1' )  || (substr($_SERVER['HTTP_HOST'], 0 , 4)  == '10.0')
                        || (substr($_SERVER['HTTP_HOST'], 0 , 7)  == 'systemname')){
      
            $_SESSION["$Chk_Server"] = "Local";
      }
      
      if( stristr($_SERVER['HTTP_HOST'], 'yourdomain.com' ) ){
      
            $_SESSION["$Chk_Server"] = "yourdomain.com";
      }
      
      
}      

You should also use complete  domain name instead of local paths to get exact path.      
0
WB-InternalCommented:
you're better off taking the time to understand what NoiS wrote then not.
0
WB-InternalCommented:
oh yeah i think script or script_name will give you a path to the current script being ran.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.