我经常发现我在我的项目需要从文件系统,以及用户浏览器访问的文件。 一个例子是上传照片。 我需要访问文件系统上的文件,以便我可以使用GD改变图像或移动它们。 但我的用户也需要能够从像一个URL访问文件example.com/uploads/myphoto.jpg
。
由于上传路径通常对应于URL我做了,似乎工作的大部分时间的函数。 就拿这些路径:
文件系统/var/www/example.com/uploads/myphoto.jpg
URL http://example.com/uploads/myphoto.jpg
如果我有一个变量设置为类似/var/www/example.com/
然后我可以从文件系统路径中减去它,然后用它作为URL的形象。
/**
* 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"
有谁知道一个更好的方式来处理呢?
Answer 1:
假设目录/path/to/root/document_root/user/file
和地址是site.com/user/file
我显示的第一个函数将获得相对万维网地址当前文件的名称。
$path = $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];
并会导致:
site.com/user/file
所述第二函数去除文档根给定的路径。
$path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $path)
鉴于我在通过/path/to/root/document_root/user/file
,我会得到
/user/file
Answer 2:
更准确的方式(包括主机端口)将使用此
function path2url($file, $Protocol='http://') {
return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}
Answer 3:
恕我直言,这样的自动化真的容易出错。 你好得多使用一些显式路径佣工(例如,一个用于上传,一个用于用户图片等),或者只是封装例如带班上传的文件。
// 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
Answer 4:
可以很容易对自己,只是定义了两种文件系统和网络文件夹中的正确位置,并与他们在前面加上图像文件名。
冥冥之中,你声明:
define('PATH_IMAGES_FS', '/var/www/example.com/uploads/');
define('PATH_IMAGES_WEB', 'uploads/');
然后,你可以根据你的需要路径之间交换:
$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
Answer 5:
试试这个:
$imgUrl = str_replace($_SERVER['DOCUMENT_ROOT'], '', $imgPath)
Answer 6:
例如,我用这一个转换C:\WAMP\WWW\myfolder\document.txt
至http://example.com/myfolder/document.txt
使用这一个:
$file_path=str_replace('\\','/',$file_path);
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path);
$file_path='http://'.$_SERVER['HTTP_HOST'].$file_path;
Answer 7:
我用这个和我一起工作:
$file_path=str_replace('\\','/',__file__);
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path);
$path='http://'.$_SERVER['HTTP_HOST'].'/'.$file_path;
如果你需要在URL格式的目录名称中加入这一行:
define('URL_DIR',dirname($path));
Answer 8:
这个简单的代码片段可以将文件路径转换为文件URL中的服务器上。 像协议和端口的某些设置应保持。
$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);
Answer 9:
下面的代码有很好的注释:
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');
Answer 10:
我总是用符号链接在我的本地开发环境和@乔治的方法在这种情况下失败:
该DOCUMENT_ROOT
设置为/Library/WebServer/Documents
,有一个符号链接/Library/WebServer/Documents/repo1 -> /Users/me/dev/web/repo1
假定以下代码在/Users/me/dev/web/repo1/example.php
$_SERVER['DOCUMENT_ROOT'] == "/Library/WebServer/Documents" //default on OS X
而
realpath('./some/relative.file') == "/Users/me/dev/web/repo1/some/relative.file"
因此,更换DOCUMENT_ROOT
与HTTP_HOST
不起作用。
我想出了这个小窍门:
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"
我认为这是很好的做法,脱颖而出,防止潜在的bug,即使我们不可能在生产环境中使用的符号链接。
Answer 11:
所有答案在这里促进str_replace()函数其中任何地方替换所有出现的字符串中,不只是在开始。 的preg_replace()将确保我们只从字符串的开头做一个精确匹配:
function remove_path($file, $path = UPLOAD_PATH) {
return preg_replace("#^($path)#", '', $file);
}
Windows可以是一个问题,即目录分隔符/和\。 请务必先更换目录分隔符:
function remove_path($file, $path = UPLOAD_PATH) {
$file = preg_replace("#([\\\\/]+)#", '/', $file);
$path = preg_replace("#([\\\\/]+)#", '/', $path);
return preg_replace("#^($path)#", '', $file);
}
我会像下面这样玩。 记的realpath()和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
文章来源: PHP - Convert File system path to URL