开发者

Apache Virtualhosts, stopping PHP throwing errors with "/"

I have a pretty stable development machine set up running Apache and using virtual hosts to keep my projects separate, and running a dyndns.org service which I use to access them. Each VHost directive typically looks like this:

<VirtualHost *:80>
    ServerName [my_internal_subdomain].[my_dyndns_name].dyndns.org
    ServerAlias home

    DocumentRoot "D:/webserver/[projectDirectory]/httpdocs"
    php_admin_value open_basedir "c:/WINDOWS/TEMP;D:/webserver/[projectDirectory]/"

    ErrorLog "D:/webserver/[projectDirectory]/logs/error.log"
    TransferLog "D:/webserver/[projectDirectory]/logs/access.log"
</VirtualHost>

Obviously [projectDirectory], [my_internal_subdomain] and [my_dyndns_name] are all values I know/change for each directive, just no need to post them here :)

One thing has always confounded me however, in PHP, if I want to require a file from say /includes/, I would expect to use:

require("/includes/myfile.php"); 

Except doing so throws an open_basedir restriction error - because "/" is trying to go, presumably to the root of D:/ - whereas I would like each virtual host to recognise that the value of DocumentRoot is in fact where I would like PHP to go if I call a file by "/".

This is how my production server seems to work, and its a bit of a pain having to code everything 开发者_Python百科to work out what the relative path to /includes/ is for the benefit of my dev machine.

I expect this is a fairly simple/obvious directive I'm missing but I can't find it. Can anyone help?


Do you mean this?

require($_SERVER['DOCUMENT_ROOT'] . '/includes/myfile.php');


require paths takes filesystem paths so "/" will always be the root of the filesystem OR paths that relate to your include_path setting. You can change your includes slightly and set the include path like this to get around it:

ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . 'D:/.../httpdocs');
require('includes/myfile.php');

This will work because it will find the includes folder in your include_path.


PHP by itself has no real concept of a DocumentRoot for its file-related functions. It seems only the file system of the server. The whole DocumentRoot business is something applied at the webserver layer.

If you want to use require('/....') in your code, you'd need to use mod_chroot (or mod_security's chroot functionality), so you can "jail" each vhost into its own directory tree, and make the / directory be whatever you want for each one.

However, chrooting has its own problems - it would lock off the rest of the file system. If your script exec()'s something externally, or connects to MySQL, or does anything on the filesystem, you'd need to have copies of those executables, .so libraries, MySQL socket file, etc... within the jail.


In linux it's more common to have a 'chrooted' environment then in windows. You may determine your root by setting a configuration directive from a file in your root and get the directory name like this

$dirname = dirname(__FILE__);
// or however you wish to arrange your affairs.
$myConfigObject->set('root',$dirname);

Edit: This approach does not nescesairly use the document root, however I find that in many cases I will have multiple instances of the same project, and that most of my php files will be outside the document root for security reasons.

It will be something along the lines of this:

/home/dir         (project root
/home/dir/stable (project instance root)
/home/dir/dev    (project instance root2)
/home/dir/stable/lib    (php files)
/home/dir/stable/web    (webroot)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜