Hi
I have a php file at, say, localhost/foo/foo/bar.php
which includes a file at localhost/foo/included.php
I need to be able to get "localhost/foo/" as a string inside included.php
If, instead of localhost/foo/foo/bar.php, it's localhost/big/burpy/lolz/here.php (still including included.php) I still need to get "localhost/foo/"
So, I need the path of the included file and not the one that the client requested.
I know when I see the solution I'm going to feel like a doofus, but it just escapes me at the moment. Help please? thanks :)
This how it got working for me :)
<?php
$path = (#$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
$path .=$_SERVER["SERVER_NAME"]. dirname($_SERVER["PHP_SELF"]);
echo $path;
?>
I figured it out myself:
$realpath = str_replace('\\', '/', dirname(__FILE__));
$whatIwanted = substr_replace(str_replace($_SERVER['DOCUMENT_ROOT'], '', $realpath), "", -6);
There we go :) Thanks for the help guys.
Inside your included file:
$yourdir = dirname(__FILE__);
or if you're using PHP 5.3.x:
$yourdir = __DIR__;
Get the document root from
// contains the document root, e.g. C:\xampp\htdocs
$docRoot = realpath($_SERVER['DOCUMENT_ROOT']);
// strip drive letter if found
if(strpos($docRoot, ':') === 1) $docRoot = substr($docRoot, 2);
// directory of included file, e.g. C:\xampp\htdocs\include
$dirInclude = realpath(dirname(__FILE__));
// strip drive letter if found
if(strpos($dirInclude, ':') === 1) $dirInclude = substr($dirInclude, 2);
// find the document root
$rootPos = strpos($dirInclude, $docRoot);
// if the path really starts with the document root
if($rootPos === 0){
// example: \xampp\htdocs\include
$visibleDir = substr($rootPos, $);
// convert backslashes to slashes and strip drive letter
$webPath = str_replace('\\', '/', $visibleDir);
// yields: http://localhost/include
echo 'http://localhost' . $webPath;
}
else{
// included file was outside the webroot, nothing to do...
}
The steps for this are:
Use dirname(__FILE__) to get the folder of the include file.
Get the server root using $_SERVER['DOCUMENT_ROOT']
Remove the document root from the include folder to get the relative include folder
Obtain the server url
Append the relative include folder to the server url
Related
I'm trying to create a folder tree from an array, taken from a string.
$folders = str_split(564);
564 can actually be any number. The goal is to create a folder structure like /5/6/4
I've managed to create all folders in a single location, using code inspired from another thread -
for ($i=0;$i<count($folders);$i++) {
for ($j=0;$j<count($folders[$i]);$j++) {
$path .= $folders[$i][$j] . "/";
mkdir("$path");
}
unset($path);
}
but this way I get all folders in the same containing path.
Furthermore, how can I create these folders in a specific location on disk? Not that familiar with advanced php, sorry :(
Thank you.
This is pretty simple.
Do a for each loop through the folder array and create a string which appends on each loop the next sub-folder:
<?php
$folders = str_split(564);
$pathToCreateFolder = '';
foreach($folders as $folder) {
$pathToCreateFolder .= DIRECTORY_SEPARATOR . $folder;
mkdir($folder);
}
You may also add the base path, where the folders should be created to initial $pathToCreateFolder.
Here you'll find a demo: http://codepad.org/aUerytTd
Or you do it as Michael mentioned in comments, with just one line:
mkdir(implode(DIRECTORY_SEPARATOR, $folders), 0777, TRUE);
The TRUE flag allows mkdir to create folders recursivley. And the implode put the directory parts together like 5/6/4. The DIRECTORY_SEPARATOR is a PHP constant for the slash (/) on unix machines or backslash (\) on windows.
Why not just do:
<?php
$directories = str_split(564);
$path = implode(DIRECTORY_SEPARATOR, $directories);
mkdir($path, 0777, true);
Don't know what you're really trying to do, but here are some hints.
There are recursive mkdir:
if(!file_exists($dir)) // check if directory is not created
{
#mkdir($dir, 0755, true); // create it recursively
}
Path you want can be made in two function calls and prefixed by some start path:
$path = 'some/path/to/cache';
$cache_node_id = 4515;
$path = $path.'/'.join('/', str_split($cache_node_id));
Resulting path can be used to create folder with the code above
So here we come to a pair of functions/methods
function getPath($node_id, $path = 'default_path')
{
return $path.'/'.join('/', str_split($node_id))
}
function createPath($node_id, $path = 'default_path');
{
$path = getPath($node_id, $path);
if(!file_exists($path)) // check if directory is not created
{
#mkdir($path, 0755, true); // create it recursively
}
}
With these you can easily create such folders everywhere you desire and get them by your number.
As mentioned earlier, the solution I got from a friend was
$folders = str_split(564);
mkdir(implode('/',$folders),0777,true);
Also, to add a location defined in a variable, I used
$folders = str_split($idimg);
mkdir($path_defined_earlier. implode('/',$folders),0777,true);
So thanks for all the answers, seems like this was the correct way to handle this.
Now the issue is that I need to the created path, so how can I store it in a variable? Sorry if this breaches any rules, if I need to create a new thread I'll do it...
I've created a function to call file from folder. But the problem is that it is not matching case. My function is
function CheckFile($var){
if($var){
$file = $_SERVER['DOCUMENT_ROOT'].'/include_folder/'.$var.'.php';
if (file_exists($file)) {
return true;
}
}
}
So if file is exists, I include it. Like if $var = profile then it will check in core folder for profile.php and if it exists then it will include it. I am including file when I am calling this function. But the problem is that it is not case sensitive. like if I look for "PrOFile" then it will include profile.php so how to solve this? Please help me if anyone can.
Use realpath() combined with converting the slashes if needed.
Examples:
// Check the filename is the same (don't worry on the path)
if (file_exists($filepath) && basename(realpath($filepath)) === basename($filepath)) {
// Check the full path, converting slashes to be sure
// Assumes final path is Lunix orientated
if (file_exists($filepath) && str_replace('\\', '/', realpath($filepath)) === $filepath) {
// Check the full path, converting slashes to be sure
// Assumes final path may not be Lunix orientated
if (file_exists($filepath) && str_replace('\\', '/', realpath($filepath)) === str_replace('\\', '/', $filepath)) {
On Windows, filenames are case-insensitive. That's just how they work.
So you need to manually code around this:
if( file_exists($file) && glob($file)[0] === $file) // assumes PHP 5.4
// older versions need a temporary variable for glob
I need to look for and echo an image file name that's located in either of these two directories named 'photoA' or 'photoB'.
This is the code I started with that tries to crawl through these directories, looking for the specified file:
$file = 'image.jpg';
$dir = array(
"http://www.mydomain.com/images/photosA/",
"http://www.mydomain.com/images/photosB/"
);
foreach( $dir as $d ){
if( file_exists( $d . $file )) {
echo $d . $file;
} else {
echo "File not in either directories.";
}
}
I feel like I'm way off with it.
You cannot use a url in file_exists, you need to use an absolute or relative path (relative to the runnings script) in the file-system of the server, so for example:
$dir = array(
"images/photosA/",
"../images/photosB/",
"/home/user/www/images/photosB/"
);
You can also use paths relative to the root of the web-server if you don't know the exact path and add the document root before that:
$dir = array(
$_SERVER['DOCUMENT_ROOT'] . "/images/photosA/",
$_SERVER['DOCUMENT_ROOT'] . "/images/photosB/"
);
(or you use it once, where you use file_exists())
Since you are running this script from within the root directory of your website, you won't need to define 'http://www.mydomain.com/' as this will cause Access Denied issues as it is not an absolute/relative file path. Instead, if the images/ folder is at the same directory level as your PHP script, all you will need to do is
$dir = array(
"images/photosA/",
"images/photosB/"
);
Otherwise, just add the absolute path as needed to make it work, but you can not put the. The rest seems as if it should work fine.
As the others said, file_exists() is for local files.
If you REALLY need to look for files over http, you can use :
$file = 'http://www.domain.com/somefile.jpg';
$file_headers = #get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$exists = true;
}
NOTE: This relies on the server returning a 404 if the image does not exist. If the server instead redirects to an index page or a pporly-coded error page, you could get a false success.
I am able to get the web path to the file like so:
$filename = 'elephant.jpg';
$path_to_file = $this->getSkinUrl('manufacturertab');
$full_path = $path_to_file . '/' . $filename;
But if the file doesn't exist, then I end up with a broken image link.
I tried this:
if(!file_exists($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_path ?>" /><?php
}
Of course that didn't work because file_exists does not work on urls.
How do I solve this?
1.)
Can I translate between system paths and web urls in Magento?
e.g. something like (pseudocode):
$system_path = $this->getSystemPath('manufacturertab');
That looks symmetrical and portable.
or
2.)
Is there some PHP or Magento function for checking remote resource existence? But that seems a waste, since the resource is really local. It would be stupid for PHP to use an http method to check a local file, wouldn't it be?
Solution I am currently using:
$system_path = Mage::getBaseDir('skin') . '/frontend/default/mytheme/manufacturertab'; // portable, but not pretty
$file_path = $system_path . '/' . $filename;
I then check if file_exists and if it does, I display the img. But I don't like the asymmetry between having to hard-code part of the path for the system path, and using a method for the url path. It would be nice to have a method for both.
Function
$localPath = Mage::getSingleton( 'core/design_package' )->getFilename( 'manufacturertab/' . $filename, array( '_type' => 'skin', '_default' => false ) );
will return the same path as
$urlPath = $this->getSkinUrl( 'manufacturertab/' . $filename );
but on your local file system. You can omit the '_default' => false parameter and it will stil work (I left it there just because getSkinUrl also sets it internaly).
Note that the parameter for getSkinUrl and getFilename can be either a file or a directory but you should always use the entire path (with file name) so that the fallback mechanism will work correctly.
Consider the situation
skin/default/default/manufacturertab/a.jpg
skin/yourtheme/default/manufacturertab/b.jpg
In this case the call to getSkinUrl or getFilename would return the path to a.jpg and b.jpg in both cases if file name is provided as a parameter but for your case where you only set the folder name it would return skin/yourtheme/default/manufacturertab/ for both cases and when you would attach the file name and check for a.jpg the check would fail. That's why you shold always provide the entire path as the parameter.
You will still have to use your own function to check if the file exists as getFilename function returns default path if file doesn't exist (returns skin/default/default/manufacturertab/foo.jpg if manufacturertab/foo.jpg doesn't exist).
it help me:
$url = getimagesize($imagepath); //print_r($url); returns an array
if (!is_array($url))
{
//if file does not exists
$imagepath=Mage::getDesign()->getSkinUrl('default path to image');
}
$fileUrl = $this->getSkinUrl('images/elephant.jpg');
$filePath = str_replace( Mage::getBaseUrl(), Mage::getBaseDir() . '/', $fileUrl);
if (file_exists($filePath)) {
// display image ($fileUrl)
}
you can use
$thumb_image = file_get_contents($full_path) //if full path is url
//then check for empty
if (#$http_response_header == NULL) {
// run check
}
you can also use curl or try this link http://junal.wordpress.com/2008/07/22/checking-if-an-image-url-exist/
Mage::getBaseDir() is what you're asking for. For your scenario, getSkinBaseDir() will perform a better job.
$filename = 'elephant.jpg';
$full_path = Mage::getDesign()->getSkinBaseDir().'/manufacturertab/'.$filename;
$full_URL=$this->getSkinUrl('manufacturertab/').$filename;
if(!is_file($full_path)) {
Mage::log('File doesn\'t exist.');
} else {
?><img src="<?php echo $full_URL ?>" /><?php
}
Note that for the <img src> you'll need the URL, not the system path. ...
is_file(), rather than file_exists(), in this case, might be a good option if you're sure you're checking a file, not a dir.
You could use the following:
$file = 'http://mysite.co.za/files/image.jpg';
$file_exists = (#fopen($file, "r")) ? true : false;
Worked for me when trying to check if an image exists on the URL
I often find that I have files in my projects that need to be accessed from the file system as well as the users browser. One example is uploading photos. I need access to the files on the file system so that I can use GD to alter the images or move them around. But my users also need to be able to access the files from a URL like example.com/uploads/myphoto.jpg.
Because the upload path usually corresponds to the URL I made up a function that seems to work most of the time. Take these paths for example:
File System
/var/www/example.com/uploads/myphoto.jpg
URL
http://example.com/uploads/myphoto.jpg
If I had a variable set to something like /var/www/example.com/ then I could subtract it from the filesystem path and then use it as the URL to the image.
/**
* Remove a given file system path from the file/path string.
* If the file/path does not contain the given path - return FALSE.
* #param string $file
* #param string $path
* #return mixed
*/
function remove_path($file, $path = UPLOAD_PATH) {
if(strpos($file, $path) !== FALSE) {
return substr($file, strlen($path));
}
}
$file = /var/www/example.com/uploads/myphoto.jpg;
print remove_path($file, /var/www/site.com/);
//prints "uploads/myphoto.jpg"
Does anyone know of a better way to handle this?
More accurate way (including host port) would be to use this
function path2url($file, $Protocol='http://') {
return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}
Assume the directory is /path/to/root/document_root/user/file and the address is site.com/user/file
The first function I am showing will get the current file's name relative to the World Wide Web Address.
$path = $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];
and would result in:
site.com/user/file
The second function strips the given path of the document root.
$path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $path)
Given I passed in /path/to/root/document_root/user/file, I would get
/user/file
IMHO such automation is really error prone. You're far better off using some explicit path helpers (eg. one for uploads, one for user pics, etc) or just encapsulate for example an uploaded file with a class.
// Some "pseudo code"
$file = UploadedFile::copy($_FILES['foo']);
$file->getPath(); // /var/www/example.org/uploads/foo.ext
$file->getUri(); // http://example.org/uploads/foo.ext
Make it easy on yourself and just define the correct locations for both the filesystem and web folders and prepend the image filename with them.
Somewhere, you'd declare:
define('PATH_IMAGES_FS', '/var/www/example.com/uploads/');
define('PATH_IMAGES_WEB', 'uploads/');
Then you can just swap between paths depending on your need:
$image_file = 'myphoto.jpg';
$file = PATH_IMAGES_FS.$image_file;
//-- stores: /var/www/example.com/uploads/myphoto.jpg
print PATH_IMAGES_WEB.$image_file;
//-- prints: uploads/myphoto.jpg
Try this:
$imgUrl = str_replace($_SERVER['DOCUMENT_ROOT'], '', $imgPath)
I've used this and worked with me:
$file_path=str_replace('\\','/',__file__);
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path);
$path='http://'.$_SERVER['HTTP_HOST'].'/'.$file_path;
And if you need the directory name in url format add this line:
define('URL_DIR',dirname($path));
The code below is well commented:
function pathToURL($path) {
//Replace backslashes to slashes if exists, because no URL use backslashes
$path = str_replace("\\", "/", realpath($path));
//if the $path does not contain the document root in it, then it is not reachable
$pos = strpos($path, $_SERVER['DOCUMENT_ROOT']);
if ($pos === false) return false;
//just cut the DOCUMENT_ROOT part of the $path
return substr($path, strlen($_SERVER['DOCUMENT_ROOT']));
//Note: usually /images is the same with http://somedomain.com/images,
// So let's not bother adding domain name here.
}
echo pathToURL('some/path/on/public/html');
For example, i used this one to convert C:\WAMP\WWW\myfolder\document.txt to http://example.com/myfolder/document.txt use this one:
$file_path=str_replace('\\','/',$file_path);
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path);
$file_path='http://'.$_SERVER['HTTP_HOST'].$file_path;
This simple snippet can convert the file path to file's url on the server. Some settings like protocol and port should be kept.
$filePath = str_replace('\\','/',$filePath);
$ssl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? true : false;
$sp = strtolower($_SERVER['SERVER_PROTOCOL']);
$protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
$port = $_SERVER['SERVER_PORT'];
$stringPort = ((!$ssl && $port == '80') || ($ssl && $port == '443')) ? '' : ':' . $port;
$host = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
$fileUrl = str_replace($_SERVER['DOCUMENT_ROOT'] ,$protocol . '://' . $host . $stringPort, $filePath);
I always use symlinks in my local development environment and #George's approach fails in this case:
The DOCUMENT_ROOT is set to /Library/WebServer/Documents and there is a symlink /Library/WebServer/Documents/repo1 -> /Users/me/dev/web/repo1
Assume that following codes are in /Users/me/dev/web/repo1/example.php
$_SERVER['DOCUMENT_ROOT'] == "/Library/WebServer/Documents" //default on OS X
while
realpath('./some/relative.file') == "/Users/me/dev/web/repo1/some/relative.file"
Thus, replacing DOCUMENT_ROOT with HTTP_HOST doesn't work.
I come up with this little trick:
function path2url($path) {
$pos = strrpos(__FILE__, $_SERVER['PHP_SELF']);
return substr(realpath($path), $pos);
}
// where
__FILE__ == "/Users/me/dev/web/repo1/example.php"
$_SERVER['PHP_SELF'] == "/web/repo1/example.php"
realpath("./some/relative.file") == "/Users/me/dev/web/repo1/some/relative.file"
// If I cut off the pre-fix part from realpath($path),
// the remainder will be full path relative to virtual host root
path2url("./some/relative.file") == "/web/repo1/some/relative.file"
I think it's good practice to fore-prevent the potential bugs even we are not likely to use symlinks in production environment.
All answers here promotes str_replace() which replaces all occurences anywhere in the string, not just in the beginning. preg_replace() will make sure we only do an exact match from the beginning of the string:
function remove_path($file, $path = UPLOAD_PATH) {
return preg_replace("#^($path)#", '', $file);
}
Windows can be a problem where directory separators / and \. Make sure you replace the directory separators first:
function remove_path($file, $path = UPLOAD_PATH) {
$file = preg_replace("#([\\\\/]+)#", '/', $file);
$path = preg_replace("#([\\\\/]+)#", '/', $path);
return preg_replace("#^($path)#", '', $file);
}
I would play with something like the following. Make note of realpath() and rtrim().
function webpath($file) {
$document_root = rtrim(preg_replace("#([\\\\/]+)#", '/', $_SERVER['DOCUMENT_ROOT']), '/');
$file = preg_replace("#([\\\\/]+)#", '/', realpath($file));
return preg_replace("#^($document_root)#", '', $file);
}
echo webpath(__FILE__); // Returns webpath to self
echo webpath('../file.ext'); // Relative paths
echo webpath('/full/path/to/file.ext'); // Full paths
One row complete solution to the "convert path to url" problem (*):
$path = "/web/htdocs/<domain>/home/path/to/file/file.ext";
$url = ( ( isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' )? 'https://' : 'http://' ).$_SERVER['HTTP_HOST'].str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', realpath($ITEM_GPX_PATH));
echo $url;
// print "http(s)://<domain>/path/to/file/file.ext"
I came to this solution thanks to the answers of George (and the respective comments of Stephanie and SWHarden) and of Rid Iculous.
Note: my solution does not answer the complete question directly, but its title; I thought to insert this answer because it can be useful to those who search on Google "php convert path to url"