2009-08-06 7 views
25

Tôi thường thấy rằng tôi có tệp trong các dự án cần được truy cập từ hệ thống tệp cũng như trình duyệt của người dùng. Một ví dụ là tải ảnh lên. Tôi cần quyền truy cập vào các tệp trên hệ thống tệp để tôi có thể sử dụng GD để thay đổi hình ảnh hoặc di chuyển chúng xung quanh. Nhưng người dùng của tôi cũng cần có thể truy cập các tệp từ một URL như example.com/uploads/myphoto.jpg.PHP - Chuyển đổi đường dẫn hệ thống tệp thành URL

Vì đường dẫn tải lên thường tương ứng với URL mà tôi đã tạo nên một hàm có vẻ hoạt động phần lớn thời gian. Thực hiện các đường dẫn ví dụ:

File System /var/www/example.com/uploads/myphoto.jpg

URL http://example.com/uploads/myphoto.jpg

Nếu tôi có một bộ biến để một cái gì đó như /var/www/example.com/ sau đó tôi có thể trừ nó khỏi đường dẫn hệ thống tập tin và sau đó sử dụng nó làm URL cho hình ảnh.

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

Có ai biết cách nào tốt hơn để xử lý việc này không?

+0

Cảm ơn. Mặc dù điều này có thể dễ bị lỗi, nhưng đó chính xác là những gì tôi cần trong trường hợp của tôi. –

Trả lời

8

Giả sử thư mục là /path/to/root/document_root/user/file và địa chỉ là site.com/user/file

Chức năng đầu tiên tôi thấy sẽ có được tên tập tin hiện tại của tương đối so với World Wide Web Address.

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

và sẽ cho kết quả:

site.com/user/file 

Chức năng thứ hai dải đường nhất định của tài liệu gốc.

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

Với tôi trôi qua trong /path/to/root/document_root/user/file, tôi sẽ nhận được

/user/file 
+2

xem xét việc sử dụng unsanitized của '$ _SERVER ['PHP_SELF']' có thể có hại. – sepehr

+0

Vâng, tôi đã tìm ra điều đó một cách khó khăn khi một số kẻ lừa bị tấn công redditmirror.cc sử dụng nó; o Ghi đè lên config.php chết tiệt. –

+0

Thật buồn cười khi mọi người vẫn tin tưởng các giá trị $ _SERVER. http://videos.code2design.com/video/play/PHP/11 – Xeoncross

6

IMHO tự động hóa như vậy thực sự là dễ bị lỗi. Bạn đang sử dụng một số trình trợ giúp đường dẫn rõ ràng hơn (ví dụ: một tệp để tải lên, một cho ảnh người dùng, v.v.) hoặc chỉ đóng gói ví dụ như một tệp được tải lên với một lớp.

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

Tôi thứ hai cách tiếp cận này! –

6

cách chính xác hơn (bao gồm cả cổng host) sẽ được sử dụng này

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

trả về $ Protocol. $ _ SERVER ['HTTP_HOST']. Str_replace ($ _ SERVER ['DOCUMENT_ROOT'], '', đường dẫn ($ file)); Thêm đường dẫn thực làm sạch URL đầu ra một cách chính xác - đã sửa khi đầu vào có ../ hoặc ./ trong đường dẫn. – ZTK

3

Làm cho nó dễ dàng trên chính mình và chỉ cần xác định các địa điểm chính xác cho cả hai hệ thống tập tin và các trang web thư mục và thêm vào trước tên tập tin hình ảnh với họ.

Một nơi nào đó, bạn muốn tuyên bố:

define('PATH_IMAGES_FS', '/var/www/example.com/uploads/'); 
define('PATH_IMAGES_WEB', 'uploads/'); 

Sau đó, bạn có thể chỉ cần trao đổi giữa những con đường phụ thuộc vào nhu cầu của bạn:

$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 
+0

Có, tôi thực sự sử dụng hằng số cho các vị trí chính - nhưng tôi e rằng điều này sẽ không giúp ích gì vì tôi không biết vị trí của tệp cho đến khi tôi tìm nạp nó.Nói cách khác, hầu hết trong tệp UPLOAD cơ sở hoặc URL - nhưng chúng cũng có thể nằm trong thư mục con hoặc thậm chí ở một nơi khác. – Xeoncross

+0

Aaaah, không có tài khoản để làm việc với nhiều hơn một địa điểm. – random

+0

Tôi nghĩ đây là cách tiếp cận tốt nhất .. Lập kế hoạch tốt giúp cuộc sống dễ dàng hơn. – Popsyjunior

2

Hãy thử điều này:

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

$ _SERVER không an toàn để sử dụng mà không có một số dạng phân tích cú pháp. – Xeoncross

1

Ví dụ, tôi đã sử dụng cái này để chuyển đổi C:\WAMP\WWW\myfolder\document.txt thành http://example.com/myfolder/document.txt sử dụng cái này:

$file_path=str_replace('\\','/',$file_path); 
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path); 
$file_path='http://'.$_SERVER['HTTP_HOST'].$file_path; 
0

Đoạn mã đơn giản này có thể chuyển đổi đường dẫn tệp thành url của tệp trên máy chủ. Một số cài đặt như giao thức và cổng nên được lưu giữ.

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

Tôi đã sử dụng này và làm việc với tôi:

$file_path=str_replace('\\','/',__file__); 
$file_path=str_replace($_SERVER['DOCUMENT_ROOT'],'',$file_path); 
$path='http://'.$_SERVER['HTTP_HOST'].'/'.$file_path; 

Và nếu bạn cần tên thư mục trong định dạng url thêm dòng này:

define('URL_DIR',dirname($path)); 
+0

tập lệnh của bạn có thể không hoạt động trên các hệ điều hành khác, do đó, người dùng DIRECTORY_SEPARATOR không đổi thay vì rõ ràng nó. – Popsyjunior

0

Đoạn code dưới đây là tốt đã nhận xét:

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

Tôi luôn là chúng tôi symlink e trong môi trường phát triển địa phương của tôi và @ cách tiếp cận của George thất bại trong trường hợp này:

Các DOCUMENT_ROOT được thiết lập để /Library/WebServer/Documents và có một liên kết tượng trưng /Library/WebServer/Documents/repo1 -> /Users/me/dev/web/repo1

Giả sử rằng mã sau nằm trong /Users/me/dev/web/repo1/example.php

$_SERVER['DOCUMENT_ROOT'] == "/Library/WebServer/Documents" //default on OS X 

trong khi

realpath('./some/relative.file') == "/Users/me/dev/web/repo1/some/relative.file" 

Do đó, thay thế DOCUMENT_ROOT bằng HTTP_HOST không hoạt động.

tôi đưa ra mánh khóe này chút:

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" 

Tôi nghĩ đó là thực hành tốt để fore-ngăn chặn các lỗi tiềm năng thậm chí chúng ta không có khả năng sử dụng liên kết tượng trưng trong môi trường sản xuất.