Do you think it is preferred to use $_SERVER['DOCUMENT_ROOT'] in website's include statements? Is it supported everywhere without any problem?
Many frameworks use dirname(__FILE__) to work out the application path based on a known file, usually the index.php
In the Zend Framework, they use the following to define the application path, which is then used everywhere in the app:
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application');
I personally prefer relative paths: include("../../some/other/path.php") Whenever I create a directory, I know exactly how my directory tree is setup, and it doesn't matter whether there is a document root or anything else available.
Furthermore, there are some cases where $_SERVER['DOCUMENT_ROOT'] may not work (eg, I have seen people have issues with it on IIS).
Related
I am new to ZEnd, any help is greatly appreciated
I had various contractors work on my site, and things got a messy, with multiple copies of the same folders in different locations. Now I am going in and trying to clean things up. FUN!!! One of the problem I am having is that the require_once statements in Zend are not finding the files they are looking for. I am having to go in and change the paths as follows. Assume that this is the code found in Zend/Gdata/App/FeedEntryParent.php
Not Working (Can't Find File):
require_once 'Zend/Gdata/App/Extension/Updated.php';
Seems to Work Fine:
require_once '/home/paul13/paul13.com/includes/library/Zend/Gdata/App/Extension/Updated.php';
The problem is that most of the require_once statements are writting like the first one. short of going in and manually editing all of them, is there a way to tell the require statements to look in the indicated directory? '/home/paul13/paul13.com/includes/library/' using php.ini? I tried entering
include_path=".:/home/paulthetutor/paulthetutors.com/includes/library"
in php.ini, but that does not seem to solve the problem.
The title of your question seems to have little to do with the content you've posted.
I had various contractors work on my site...are not finding the files
You've paid contractors to deliver code which doesn't work?
The problem is obviously that the path in the first
No - the problem is that your include paths are not set up correctly. If you're using an include path as a mechanism to avoid typing lots of stuff then you're doing it wrong. Your include path should not include entries pointing inside a directory tree maintained by someone else. Nor should you be changing this structure without a very specific and valid objective.
As a temporary workaround until you fix the include/require statements to what they should have been in the first place, then change your include path - either in php.ini, in httpd.conf, in .htaccess, via an auto-prepend or at the top of every script.
(BTW you're confusing folders with directories)
The folder you mentioned in the question is part of the Zend library. You can check if you have a library folder inside your Zend Framework project and whether it contains the file
'Zend/Gdata/App/Extension/Updated.php'
To include the entire ZF library, use the following code either in your public/index.php or in your Bootstrap.php file.
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
And yes, selectively remove the require statements one by one and locally copied versions of library files (after making sure that they do not have updated codes, ofcourse).
You might want to check the default Zend Framework application structure here to compare the folder structures.
what are the pros and cons of using this :
$globals['server_url'] = dirname(__FILE__);
$globals['mainfiles'] = dirname(__FILE__).'/main';
and the pros and cons of using this :
$globals['server_url'] = '/srv/www/htdocs/somwhere/';
$globals['mainfiles'] = '/srv/www/htdocs/somwhere/main';
And what do you suggest.
by the way: these are set in config.php file which is called by other files as well, to stop directory conflicts when including files we use it like this :
require_once($globals['server_url'].'/test.php');
dirname(__FILE__) or __DIR__ are better than '/srv/www/htdocs/somwhere/' because they will keep working the day you'll move or rename your folders, or you migrate to another server or another OS.
Portability and flexibility are the main words here.
And globals are bad.
The __FILE__ method works fine, but you need to be aware of where the file is. If you move the file to another directory, the value will change and could potentially break anything that depends on it.
On the other hand, hard coding the path will work fine as well, but you'll need to make sure that it is valid if you ever the move the files to a different directory.
The right solution is personal preference. I would probably go with the __FILE__ method (especially if this is code you will be distributing to other servers/users).
Normally, the $_SERVER superglobal is what you would need, in particular $_SERVER['DOCUMENT_ROOT']. Documentation here.
But if you have applications that completely live in separate subtrees of DOCUMENT_ROOT, you could change the include_path, e.g., like this (but you may want to use some parent dir or subdir of __DIR__):
ini_set('include_path', __DIR__);
If you want to keep the default include_path too, it becomes this:
ini_set('include_path', ini_get('include_path').';'.__DIR__);
Once you have set your include_path, your example becomes simply
require_once('test.php');
And of course hardcoding absolute paths in your application makes it hard and error-prone to move it - in full or in part - on the same server or to another server.
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'].
in my config.php where i have all constants i set the PATH to a absolute path.
but this means that when i move my application folder i have to change this path.
i wondered if its better to set a relative path, in that way whenever i move my application between production and development folder, i dont have to change it.
how do you guys do when you move between folders?
The best way I've found is to do the following:
define("PATH", realpath(dirname(__FILE__)));
That gives you the directory of the current file. If you do this in your settings/bootstrap/init file, you'll have it available to your application, and it will work for any file system.
__FILE__ is your friend.
define('BASE_PATH', dirname(realpath(__FILE__)));
This will make your scripts more portable.
Include a file like this
include BASE_PATH . 'includes/header.php';
IMO, absolute paths are bad news. Even if you don't plan to move, your hosting provider could move you, like DreamHost recently did to me. I was fine....
But there are 14 references to "path" on their wiki:
http://wiki.dreamhost.com/Server_Moves
I do three things to solve this:
The first is to use paths relative to the current file and include things using dirname(__FILE__).
The second is to use a loader include that all the pages load. This file has one responsibility: to find the include directory, usually via a relative call. So long as this relative relationship stays, it doesn't need changing.
I also like to support custom settings that belong to the installation rather than the codebase. This is done by an include mechanism and overrides a few settings that will be specific for the server the code is on.
I'm brand new to php and I'm trying to work with some includes in my site and can't quite figure out how to make them all work correctly.
My site structure is as follows
/ROOT/
Config.php
Index.php
/ADMINISTRATION/
Index.php
mustInclude.php
/USERS/
Index.php
If "mustInclude.php" includes "Config.php" and Index.php includes "mustInclude.php" everything works fine, but as soon as I try to include "mustInclude.php" into /USERS/Index.php it breaks because "mustInclude.php" is using a path like include '../config.php'; and that isn't the same relative path for /USERS/Index.php as for /ADMINISTRATION/Index.php
I'm not really sure what to do here.
This is on my local machine for now. Using $_SERVER['DOCUMENT_ROOT'] gives me errors because it outputs my file structure (/Users/James/Sites) rather than my web structure (http://localhost/mysite)
Help?
I suggest defining some kind of "global base path" and deducing the other paths from there. Like,
define('BASE_PATH', '/home/me/');
...
include(BASE_PATH . 'Config.php');
include(BASE_PATH . 'subdirectory/other.php');
and so on. This kind of (semi)absolute paths are less fragile than relative paths containing lots of ../s. (Not to say that there's anything fundamentally wrong with relative paths, but they're harder to get just right and tend to break more easily. If /a includes b/c and b/c includes ../d/e, is that relative to /b/ or relative to /, or does it depend on whether we started from /a vs. called b/c directly? I don't even know. Better just use the absolute paths, they're easy and unambiguous :-).
IMO the best way to include files from anywhere in your application directory structure is to add the root folder of your app to your PHP include path:
<?php
set_include_path(get_include_path().PATH_SEPARATOR."/Users/James/Sites/app_name");
Then, just include files using their paths relative to the application root folder, for example:
<?php
require_once('ADMINISTRATION/USERS/Index.php');
Instead of using '../config.php' try using
dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'config.php'
This way you will always know that one level above is one level above from the current file.
you can use __FILE__