2009-08-06 17 views
25

A menudo encuentro que tengo archivos en mis proyectos a los que se debe acceder desde el sistema de archivos y desde el navegador de los usuarios. Un ejemplo es subir fotos. Necesito acceso a los archivos en el sistema de archivos para poder usar GD para alterar las imágenes o moverlas. Pero mis usuarios también deben poder acceder a los archivos desde una URL como example.com/uploads/myphoto.jpg.PHP - Convertir la ruta del sistema de archivos a la URL

Como la ruta de carga normalmente corresponde a la URL, constituí una función que parece funcionar la mayor parte del tiempo. Tome estos caminos, por ejemplo:

sistema de archivos /var/www/example.com/uploads/myphoto.jpg

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

Si tuviera un conjunto de variables a algo como /var/www/example.com/, entonces podría restarlo de la ruta del sistema de archivos y luego usarlo como la URL de la imagen.

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

¿Alguien sabe de una mejor manera de manejar esto?

+0

Gracias. Si bien esto podría ser propenso a errores, es exactamente lo que necesito en mi caso. –

Respuesta

8

asumir el directorio es /path/to/root/document_root/user/file y la dirección es site.com/user/file

La primera función que les estoy mostrando recibirá el nombre del archivo actual en relación con el mundo de la dirección Wide Web.

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

y daría como resultado:

site.com/user/file 

La segunda función tiras de la ruta dada de la raíz del documento.

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

Dado que pasé en /path/to/root/document_root/user/file, me gustaría tener

/user/file 
+2

teniendo en cuenta que el uso no esterilizado de '$ _SERVER ['PHP_SELF']' podría ser dañino. – sepehr

+0

Sí, lo descubrí de la manera difícil cuando un tonto hackeó redditmirror.cc usando eso; o Sobrescribió el maldito config.php. –

+0

Es curioso que la gente todavía confíe en los valores de $ _SERVER. http://videos.code2design.com/video/play/PHP/11 – Xeoncross

6

mi humilde opinión esta automatización es realmente propenso a errores. Es mucho mejor utilizar algunos ayudantes de ruta explícitos (por ejemplo, uno para las cargas, uno para las fotos de los usuarios, etc.) o simplemente encapsular, por ejemplo, un archivo cargado con una clase.

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

¡En segundo lugar este enfoque! –

6

manera más precisa (incluyendo puerto host) sería utilizar este

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

return $ Protocol. $ _ SERVER ['HTTP_HOST']. Str_replace ($ _ SERVER ['DOCUMENT_ROOT'], '', realpath ($ file)); Agregando realpath limpia la URL de salida correctamente, incluso cuando la entrada tiene ../ o ./ en la ruta. – ZTK

3

Que sea fácil para ti y simplemente definir las ubicaciones correctas tanto para las carpetas del sistema de archivos y de la tela y anteponer el nombre del archivo de imagen con ellos.

En algún lugar, que había declarar:

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

A continuación, sólo se puede intercambiar entre las trayectorias en función de su necesidad:

$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

Sí, en realidad sí uso constantes para las ubicaciones principales, pero me temo que esto no ayudará ya que no conozco la ubicación del archivo hasta que lo recoja.En otras palabras, la mayoría en el archivo base de carga o URL, pero también pueden estar en subcarpetas o incluso en otro lugar. – Xeoncross

+0

Aaaah, no cuenta para trabajar con más de una ubicación. – random

+0

Creo que este es el mejor enfoque ... Una buena planificación hace la vida más fácil. – Popsyjunior

2

Prueba esto:

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

$ _SERVER no es seguro de usar sin algún tipo de análisis sintáctico. – Xeoncross

1

Por ejemplo, Utilicé este para convertir C:\WAMP\WWW\myfolder\document.txt a http://example.com/myfolder/document.txt utilice este:

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

Este simple fragmento de código puede convertir la ruta del archivo a la URL del archivo en el servidor. Algunas configuraciones como protocolo y puerto deben mantenerse.

 $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

He utilizado este y trabajaba conmigo:

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

Y si necesita el nombre del directorio en formato URL añadir esta línea:

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

su secuencia de comandos podría no funcionar en otros sistemas operativos, por lo tanto, el usuario DIRECTORY_SEPARATOR es constante en lugar de explícitamente. – Popsyjunior

0

El código siguiente es así Comentados:

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

Yo siempre usamos e enlaces simbólicos en mi entorno de desarrollo local y @ enfoque de George falla en este caso:

El DOCUMENT_ROOT se establece en /Library/WebServer/Documents y hay un enlace simbólico /Library/WebServer/Documents/repo1 -> /Users/me/dev/web/repo1

Supongamos que los códigos siguientes están en /Users/me/dev/web/repo1/example.php

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

mientras que

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

Por lo tanto, reemplazando DOCUMENT_ROOT con HTTP_HOST no funciona.

llego a tener este pequeño truco:

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" 

Creo que es una buena práctica delanteras prevenir los errores potenciales incluso no somos propensos a utilizar enlaces simbólicos en el entorno de producción.

Cuestiones relacionadas