php paths that work on both local (mac) and remote server - php

I'm testing a website on my local machine and I'm wondering what would be the best way to write paths to make sure they work when I upload the site to its final location.
In general I'm a bit confused about paths, and in many cases I have to 'tweak' each path until it works, so wouldn't want to be forced to do the same on a production site!
I'm not clear when to use $_SERVER['DOCUMENT_ROOT'].
For example, I have a directory that I want to scan, which is just under the root. So why can't I just use "/dirname"?
$dir = $_SERVER['DOCUMENT_ROOT'] . '/uploads'; //this works
// $dir = "/uploads"; //this doesn't work
if (is_dir($dir)) {
//do something..
}

I'm not clear when to use
$_SERVER['DOCUMENT_ROOT']. For
example, I have a directory that I
want to scan, which is just under the
root. So why can't I just use
"/dirname"?
When you work with paths in the php file the root (/) is the root of the filesystem, not the root you get when you visit your website.
So $dir = "/uploads"; gives you the filesystem root.
To minify your problems I would declare a variable in a configuration file that specifies the root of your php application, and use that path+whatever more is needed.

As adamse mentioned, the reason you can't use the '/path' is because it points to the root of the filesystem.
However, instead of declaring a variable that defines the root, I recommend using dirname(__FILE__) to retrieve the full path to the directory that the calling file is in.
From there, append relative path information to the file you want and you end up with a complete path, fully dynamically.
For example, if you want to include the 'header.php' file in the directory above the file that you wish to include it in use:
include(dirname(__FILE__) . '/../header.php');
The beauty of that is that PHP will always automatically convert the forward slash to the directory separator required for the host OS.

I would define a variable/constant that describes the absolute filesystem path to the application. Something like this:
$appDir = rtrim(str_replace('\\', '/', realpath(dirname(__FILE__))), '/');
Then you have this base path you can address your application’s files from:
include $appDir.'/library/foo/bar.php';
Or you even change your include path to that directory:
set_include_path($appDir);

Related

php check file_exists() out of the third level to the root dir

I struggle with this, any suggestions?
SERVER HTTPDOCS DIR
/images <--MAINDOMAIN - domain.com
/m <--SUBDOMAIN (Third level) ROOT DIR OF m.domain.com
*FROM m.domain.com/test.php*
$dir="../images"; //Trying to read outside the subdomain root dir
if (is_dir($dir)) {
$oggetto = #opendir($dir);
while (false !== ($files = #readdir($oggetto))) {
if($files != "." && $files != "..") {//print filename}
It does not recognize the directory.
From the PHP docs for is_dir(), regarding the first passed parameter:
Path to the file. If filename is a relative filename, it will be checked relative to the current working directory. If filename is a symbolic or hard link then the link will be resolved and checked. If you have enabled safe mode, or open_basedir further restrictions may apply.
In other words, if you specify a relative path, it will be considered relative to the currently executing script, which is why your script works in the first case, but not in the second. Personally I perfer to use full paths when operating on files and directories to make sure I know what I'm pointing at. To poke around a bit and see what I'm talking about try this:
<?php
$current_dir = dirname(__FILE__);
$path = realpath( $current_dir . '/../images' );
var_dump( $path );
In general, PHP frameworks tend to specify some full paths during their bootstrap, like absolute path to the document root, the application folder, the log folder, etc. and then use those paths whenever specifying a path to a file. This is handy and tends to be very stable because the bootstrap file tends to stay in the same filepath, whereas with the problem you are experiencing, your path resolution breaks when you move the script from folder to folder. I say all this by way of saying you might consider creating a "document root" variable in a header file, for example, include that header file in each of your scripts, and then use that variable when you need to create filepaths.

how can I get a URL from an absolute folder path?

I have a php function that is moving files for me. It requires absolute paths to place those files (/Applications/MAMP/HTdocs/mysite/myfolder)
how can a turn this folder path string into a url (http://mysite.com/myfolder) so that I can create links to the files on the fly?
I do not know necessarily the names of the folders, as the software could be run in many locations.
Many thanks.
Obviously, you need to know server root for such a calculation.
Luclikly, $_SERVER['DOCUMENT_ROOT'] contains this path.
So, just subtract server root path from the given path:
$path = '/Applications/MAMP/HTdocs/mysite/myfolder';
$approot = substr($path,strlen($_SERVER['DOCUMENT_ROOT']));
check if you have a drive letter in the DOCUMENT_ROOT, and correct the code if necessary
Note that adding http://mysite.com is unnecessary and useless. just /myfolder/ is what you really need.
You can check for this value: $_SERVER["DOCUMENT_ROOT"];
That is the root of your website. If you have the folder and replace the $_SERVER["DOCUMENT_ROOT"] with the $_SERVER["HTTP_HOST"] you will get the URL to the folder/file
If mysite folder is within HTdocs then you can access it using http://yourdomain/mysite, (if HTodcs is your home directory)

PHP - Is there a decent way so that the calling of mkdir creates folders relative to the web root?

The directory and file structure is as follows:
C:\xampp\htdocs\PHP_Upload_Image_MKDIR\uploaded
C:\xampp\htdocs\testA.php // as follows
$userID = 's002';
$uploadFolder = '/PHP_Upload_Image_MKDIR/uploaded/';
$userDir = $uploadFolder . $userID;
mkdir($userDir, 0700);
If I call testA.php, then the following folder will be created.
C:\PHP_Upload_Image_MKDIR\uploaded\s002
However, the desired result should be the following:
C:\xampp\htdocs\PHP_Upload_Image_MKDIR\uploaded\s002
I would like to know a decent method so that the mkdir creates folder relative to the root of the web
C:\xampp\htdocs\
or
C:\wamp\www
Then in the future, I don't have problems to move this application to a web hosting site.
Thank you
You can:
Create a file with defines that's always included and where you define what's the server root (or whatever prefix) so that you prepend it to the directory.
Use a relative directory to the script. The directory of the script can be obtained with dirname(__FILE__).
Use a relative path to the current directory. The current directory, if not changed, is usually the directory of the PHP script that was originally called (usually not a good option).
Use $_SERVER[DOCUMENT_ROOT] (not a very good option, you might want your application in a subdirectory, and whether this value is available depends on the web server).
$uploadFolder = $_SERVER['DOCUMENT_ROOT'] . '/PHP_Upload_Image_MKDIR/uploaded/';

Properly navigating relative local paths in PHP

I'm having trouble specifically with the getimagesize function. I'm making the function call from /item/ajax/image.php relative to the domain's HTTP root. I'm trying to get the dimensions of an image stored at /portfolio/15/image.jpg. From what I understand, the function takes a filename as an argument, so I tried the following:
getimagesize('/portfolio/15/image.jpg')
And
getimagesize('../../portfolio/15/image.jpg')
But both of them just threw PHP errors.
try prefixing below to path:
$_SERVER['DOCUMENT_ROOT']
Relative paths always start from the file that is executed, which is most likely index.php. This is true for included files as well. This means in any file within you project relative paths start from your index.php. (Except a chdir() is done before)
I think it is really bad code to have paths like "../../file.ext" or the like. Define a Constant that has the full path to your application (eg: $_SERVER['DOCUMENT_ROOT']) and prepend it to any path you're using.
Example:
# somewhere in your index.php
define('ROOT_PATH', $_SERVER['DOCUMENT_ROOT']);
# in any included file
$my_path = ROOT_PATH."/portfolio/14/image.jpg"
This is imho the cleanest and most readable way to define paths.
In PHP "/" is not the same as the Apache "/" (web root). In PHP "/" refers to the system root. You should use paths relative to your PHP script location ('portfolio/15/image.jpg' if your script and the 'portfolio' folder are in the same location)
The filename you enter is not related to the http root but should be an existing path in the file system of your web server.
To see what goes wrong you could enter:
realpath('../../portfolio/15/image.jpg')
To see what directory you end up at.
Or use:
imagesize(dirname(__FILE__) . '/../../portfolio/15/image.jpg')
to get the full directory qualification.
As an alternative you can use the web address, but you should specify the full url:
getimagesize('http://yoursite.com/portfolio/15/image.jpg')
However, this is a slower option.

How do I set an absolute include path in PHP?

In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:
/images/some_image.jpg
I can put that path in any file in any subdirectory, and it will point to the right image.
With PHP, I tried something similar:
include("/includes/header.php");
...but that doesn't work.
I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:
Using a . in the include path allows for relative includes as it means the current directory.
Relative includes are exactly what I don't want.
How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)
Clarification
My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)
Update
I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.
One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.
Anyway, problem solved! :)
What I do is put a config.php file in my root directory. This file is included by all PHP files in my project. In that config.php file, I then do the following;
define( 'ROOT_DIR', dirname(__FILE__) );
Then in all files, I know what the root of my project is and can do stuff like this
require_once( ROOT_DIR.'/include/functions.php' );
Sorry, no bonus points for getting outside of the public directory ;) This also has the unfortunate side affect that you still need a relative path for finding config.php, but it makes the rest of your includes much easier.
One strategy
I don't know if this is the best way, but it has worked for me.
$root = $_SERVER['DOCUMENT_ROOT'];
include($root."/path/to/file.php");
The include_path setting works like $PATH in unix (there is a similar setting in Windows too).It contains multiple directory names, seperated by colons (:). When you include or require a file, these directories are searched in order, until a match is found or all directories are searched.
So, to make sure that your application always includes from your path if the file exists there, simply put your include dir first in the list of directories.
ini_set("include_path", "/your_include_path:".ini_get("include_path"));
This way, your include directory is searched first, and then the original search path (by default the current directory, and then PEAR). If you have no problem modifying include_path, then this is the solution for you.
There is nothing in include/require that prohibits you from using absolute an path.
so your example
include('/includes/header.php');
should work just fine. Assuming the path and file are corect and have the correct permissions set.
(and thereby allow you to include whatever file you like, in- or outside your document root)
This behaviour is however considered to be a possible security risk. Therefore, the system administrator can set the open_basedir directive.
This directive configures where you can include/require your files from and it might just be your problem.
Some control panels (plesk for example) set this directive to be the same as the document root by default.
as for the '.' syntax:
/home/username/public_html <- absolute path
public_html <- relative path
./public_html <- same as the path above
../username/public_html <- another relative path
However, I usually use a slightly different option:
require_once(__DIR__ . '/Factories/ViewFactory.php');
With this edition, you specify an absolute path, relative to the file that contains the require_once() statement.
Another option is to create a file in the $_SERVER['DOCUMENT_ROOT'] directory with the definition of your absolute path.
For example, if your $_SERVER['DOCUMENT_ROOT'] directory is
C:\wamp\www\
create a file (i.e. my_paths.php) containing this
<?php if(!defined('MY_ABS_PATH')) define('MY_ABS_PATH',$_SERVER['DOCUMENT_ROOT'].'MyProyect/')
Now you only need to include in every file inside your MyProyect folder this file (my_paths.php), so you can user MY_ABS_PATH as an absolute path for MyProject.
Not directly answering your question but something to remember:
When using includes with allow_url_include on in your ini beware that, when accessing sessions from included files, if from a script you include one file using an absolute file reference and then include a second file from on your local server using a url file reference that they have different variable scope and the same session will not be seen from both included files. The original session won't be seen from the url included file.
from: http://us2.php.net/manual/en/function.include.php#84052
hey all...i had a similar problem with my cms system.
i needed a hard path for some security aspects.
think the best way is like rob wrote. for quick an dirty coding
think this works also..:-)
<?php
$path = getcwd();
$myfile = "/test.inc.php";
/*
getcwd () points to:
/usr/srv/apache/htdocs/myworkingdir (as example)
echo ($path.$myfile);
would return...
/usr/srv/apache/htdocs/myworkingdir/test.inc.php
access outside your working directory is not allowed.
*/
includ_once ($path.$myfile);
//some code
?>
nice day
strtok
I follow Wordpress's example on this one. I go and define a root path, normally the document root, and then go define a bunch of other path's along with that (one for each of my class dirs. IE: database, users, html, etc). Often I will define the root path manually instead of relying on a server variable.
Example
if($_SERVER['SERVERNAME'] == "localhost")
{
define("ABS_PATH", "/path/to/upper/most/directory"); // Manual
}
else
{
define("ABS_PATH, dirname(__FILE__));
// This defines the path as the directory of the containing file, normally a config.php
}
// define other paths...
include(ABS_PATH."/mystuff.php");
Thanks - this is one of 2 links that com up if you google for php apache windows absolute path.
As a newbie to intermed PHP developer I didnt understand why absolute paths on apache windopws systems would be c:\xampp\htdocs (apache document root - XAMPP default) instead of /
thus if in http//localhost/myapp/subfolder1/subfolder2/myfile.php I wanted to include a file from http//localhost/myapp
I would need to specify it as:
include("c:\xampp\htdocs\myapp\includeme.php")
or
include("../../includeme.php")
AND NOT
include("/myapp/includeme.php")
I've come up with a single line of code to set at top of my every php script as to compensate:
<?php if(!$root) for($i=count(explode("/",$_SERVER["PHP_SELF"]));$i>2;$i--) $root .= "../"; ?>
By this building $root to bee "../" steps up in hierarchy from wherever the file is placed.
Whenever I want to include with an absolut path the line will be:
<?php include($root."some/include/directory/file.php"); ?>
I don't really like it, seems as an awkward way to solve it, but it seem to work whatever system php runs on and wherever the file is placed, making it system independent.
To reach files outside the web directory add some more ../ after $root, e.g. $root."../external/file.txt".

Categories