web-dev-qa-db-fra.com

PHP - Convertir le chemin du système de fichiers en URL

Je constate souvent dans mes projets que des fichiers doivent être accessibles à partir du système de fichiers ainsi que du navigateur de l'utilisateur. Un exemple est le téléchargement de photos. J'ai besoin d'accéder aux fichiers du système de fichiers pour pouvoir utiliser D.ieu afin de modifier les images ou de les déplacer. Mais mes utilisateurs doivent également pouvoir accéder aux fichiers à partir d'une URL telle que example.com/uploads/myphoto.jpg.

Parce que le chemin de téléchargement correspond généralement à l'URL, j'ai créé une fonction qui semble fonctionner la plupart du temps. Prenons ces chemins par exemple:

Système de fichiers /Var/www/example.com/uploads/myphoto.jpg

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

Si j'avais une variable définie à quelque chose comme /var/www/example.com/, je pourrais alors la soustraire du chemin du système de fichiers, puis l'utiliser comme URL de l'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"

Est-ce que quelqu'un connaît une meilleure façon de gérer cela?

25
Xeoncross

Supposons que le répertoire est /path/to/root/document_root/user/file et que l'adresse est site.com/user/file

La première fonction que je montre affichera le nom du fichier actuel par rapport à l’adresse Internet.

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

et aboutirait à:

site.com/user/file

La deuxième fonction supprime le chemin donné de la racine du document.

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

Étant donné que je passais en /path/to/root/document_root/user/file, j'obtiendrais

/user/file
8
Tyler Carter

Un moyen plus précis (y compris le port de l’hôte) serait d’utiliser cette

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

IMHO Une telle automatisation est vraiment sujette aux erreurs. Vous feriez bien mieux d'utiliser des aides de chemin d'accès explicites (par exemple, un pour les téléchargements, un pour les images utilisateur, etc.) ou simplement encapsuler, par exemple, un fichier téléchargé avec une classe.

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

Simplifiez-vous la vie en définissant les emplacements corrects pour le système de fichiers et les dossiers Web et ajoutez-y le nom de fichier image.

Quelque part, vous déclareriez:

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

Ensuite, vous pouvez simplement permuter les chemins en fonction de vos besoins:

$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

Essaye ça:

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

J'ai utilisé cela et travaillé avec moi:

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

Et si vous avez besoin du nom du répertoire au format url, ajoutez cette ligne:

define('URL_DIR',dirname($path));
1
Daban

Par exemple, j'ai utilisé celui-ci pour convertir C:\WAMP\WWW\myfolder\document.txt en http://example.com/myfolder/document.txt utiliser celui-ci:

$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

Toutes les réponses ici promeuvent str_replace () qui remplace toutes les occurrences n'importe où dans la chaîne, pas seulement au début. preg_replace () s'assurera que nous ne faisons une correspondance exacte qu'au début de la chaîne:

function remove_path($file, $path = UPLOAD_PATH) {
  return preg_replace("#^($path)#", '', $file);
}

Windows peut être un problème où les séparateurs de répertoires/et \. Assurez-vous de remplacer les séparateurs de répertoires en premier:

function remove_path($file, $path = UPLOAD_PATH) {
  $file = preg_replace("#([\\\\/]+)#", '/', $file);
  $path = preg_replace("#([\\\\/]+)#", '/', $path);
  return preg_replace("#^($path)#", '', $file);
}

Je voudrais jouer avec quelque chose comme ce qui suit. Prenez note de realpath () et de 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

J'utilise toujours des liens symboliques dans mon environnement de développement local et l'approche de @ George échoue dans ce cas:

Le DOCUMENT_ROOT est défini sur /Library/WebServer/Documents et il existe un lien symbolique /Library/WebServer/Documents/repo1 -> /Users/me/dev/web/repo1

Supposons que les codes suivants sont dans /Users/me/dev/web/repo1/example.php

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

tandis que

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

Ainsi, remplacer DOCUMENT_ROOT par HTTP_Host ne fonctionnera pas.

Je viens avec ce petit truc:

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"

Je pense que c'est une bonne pratique d'éviter au préalable les bugs potentiels même si nous ne sommes pas susceptibles d'utiliser des liens symboliques dans un environnement de production.

0
Nandiin Bao

Cet extrait peut convertir le chemin du fichier en URL du fichier sur le serveur. Certains paramètres tels que protocole et port doivent être conservés.

        $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
Anderson Krüger

Le code ci-dessous est bien commenté:

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