web-dev-qa-db-ja.com

PHP-ファイルシステムパスをURLに変換

私のプロジェクトには、ユーザーのブラウザだけでなく、ファイルシステムからもアクセスする必要があるファイルがあることがよくあります。 1つの例は写真のアップロードです。 Gdを使用して画像を変更したり移動したりできるように、ファイルシステム上のファイルにアクセスする必要があります。しかし、私のユーザーはexample.com/uploads/myphoto.jpgのようなURLからファイルにアクセスできる必要もあります。

アップロードパスは通常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"

誰かがこれを処理するより良い方法を知っていますか?

27
Xeoncross

ディレクトリは/path/to/root/document_root/user/fileおよびアドレスはsite.com/user/file

最初に表示する関数は、World Wide Webアドレスに関連する現在のファイルの名前を取得します。

$path = $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];

結果は次のようになります:

site.com/user/file

2番目の関数は、ドキュメントルートの指定されたパスを削除します。

$path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $path)

/path/to/root/document_root/user/file、私は得るでしょう

/user/file
8
Tyler Carter

より正確な方法(ホストポートを含む)はこれを使用することです

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

私見そのような自動化は本当にエラーが発生しやすいです。いくつかの明示的なパスヘルパー(たとえば、アップロード用、ユーザーの写真用など)を使用するか、たとえば、アップロードされたファイルをクラスでカプセル化するほうがはるかに便利です。

// 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
6
Philippe Gerber

自分で簡単にして、ファイルシステムと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
3
random

これを試して:

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

私はこれを使用して私と一緒に作業しました:

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

たとえば、これを使用してC:\WAMP\WWW\myfolder\document.txthttp://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;
1
T.Todua

ここでのすべての回答は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
0
tim

私は常にローカル開発環境でシンボリックリンクを使用しており、この場合@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_ROOTHTTP_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"

本番環境でシンボリックリンクを使用する可能性が低い場合でも、潜在的なバグを事前に防ぐことは良い習慣だと思います。

0

この単純なスニペットは、ファイルパスをサーバー上のファイルの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);
0

以下のコードはよくコメントされています:

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');
0
Fandi Susanto