PHP - 将文件系统路径转换为 ​​URL

发布于 2024-07-29 21:18:02 字数 1071 浏览 3 评论 0原文

我经常发现项目中的文件需要从文件系统和用户浏览器访问。 一个例子是上传照片。 我需要访问文件系统上的文件,以便可以使用 GD 来更改图像或移动它们。 但我的用户还需要能够从 example.com/uploads/myphoto.jpg 这样的 URL 访问文件。

因为上传路径通常对应于 URL,所以我编写了一个似乎在大多数情况下都能工作的函数。 以这些路径为例:

文件系统 /var/www/example.com/uploads/myphoto.jpg

网址 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"

有谁知道更好的方法来处理这个问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

烛影斜 2024-08-05 21:18:27

一行完整解决“将路径转换为url”问题(*):

$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"

由于乔治(以及斯蒂芬妮和 SW哈登的各自评论)和摆脱 Iculous

注意:我的解决方案并不直接回答完整的问题,而是回答其标题; 我想插入这个答案,因为它对于那些在 Google 上搜索“php 将路径转换为 ​​url”的人很有用

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"

德意的啸 2024-08-05 21:18:25

这里的所有答案都提倡 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

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
温馨耳语 2024-08-05 21:18:23

我总是在本地开发环境中使用符号链接,而 @George 的方法在这种情况下会失败:

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< /code> 与 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"

我认为即使我们不太可能在生产环境中使用符号链接,也是预防潜在错误的好习惯。

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.

煮茶煮酒煮时光 2024-08-05 21:18:21

这个简单的代码片段可以将文件路径转换为服务器上文件的 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);

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);
累赘 2024-08-05 21:18:19

例如,我用这个将 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;

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;
诺曦 2024-08-05 21:18:16

下面的代码注释得很好:

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');

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');
﹂绝世的画 2024-08-05 21:18:15

我已经使用过这个并与我一起工作:

$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));

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));
一桥轻雨一伞开 2024-08-05 21:18:12

尝试这个:

$imgUrl = str_replace($_SERVER['DOCUMENT_ROOT'], '', $imgPath)

Try this:

$imgUrl = str_replace($_SERVER['DOCUMENT_ROOT'], '', $imgPath)
╄→承喏 2024-08-05 21:18:10

让自己轻松起来,只需为文件系统和 Web 文件夹定义正确的位置,并在前面加上图像文件名即可。

在某个地方,您可以声明:

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

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
半世晨晓 2024-08-05 21:18:08

恕我直言,这样的自动化确实很容易出错。 您最好使用一些显式路径助手(例如,一个用于上传,一个用于用户图片等),或者只是用一个类封装例如上传的文件。

// 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

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
明媚殇 2024-08-05 21:18:07

假设目录是 /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

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
星光不落少年眉 2024-08-05 21:18:05

更准确的方法(包括主机端口)是使用这个

function path2url($file, $Protocol='http://') {
    return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文