78 votes

Comment joindre des chaînes de chemin de système de fichiers en PHP?

Est-il intégré la fonction en PHP de façon intelligente le chemin de jointure des chaînes? La fonction, compte tenu de "abc/de/" et "/fg/x.php" en tant qu'arguments, devrait revenir "abc/de/fg/x.php"; le même résultat devrait être donnée à l'aide de "abc/de" et "fg/x.php" comme arguments de cette fonction.

Si non, est-il disponible de la classe? Il pourrait également être utile pour le fractionnement des chemins d'accès ou de retirer des parties d'entre eux. Si vous avez écrit quelque chose, peut vous partagez vos code ici?

C'est ok pour toujours utiliser "/", je suis codant pour Linux seulement.

En Python il y a os.path.join(), ce qui est excellent.

134voto

Riccardo Galli Points 2653
 function join_paths() {
    $paths = array();

    foreach (func_get_args() as $arg) {
        if ($arg !== '') { $paths[] = $arg; }
    }

    return preg_replace('#/+#','/',join('/', $paths));
}
 

Ma solution est plus simple et plus semblable au fonctionnement de Python os.path.join.

Considérons ces cas de test

 array               my version    @deceze      @david_miller    @mark

['','']             ''            ''           '/'              '/'
['','/']            '/'           ''           '/'              '/'
['/','a']           '/a'          'a'          '//a'            '/a'
['/','/a']          '/a'          'a'          '//a'            '//a'
['abc','def']       'abc/def'     'abc/def'    'abc/def'        'abc/def'
['abc','/def']      'abc/def'     'abc/def'    'abc/def'        'abc//def'
['/abc','def']      '/abc/def'    'abc/def'    '/abc/def'       '/abc/def'
['','foo.jpg']      'foo.jpg'     'foo.jpg'    '/foo.jpg'       '/foo.jpg'
['dir','0','a.jpg'] 'dir/0/a.jpg' 'dir/a.jpg'  'dir/0/a.jpg'    'dir/0/a.txt'
 

54voto

deceze Points 200115

Puisque cela semble être une question populaire et les commentaires sont de remplissage avec des fonctionnalités de "suggestions" ou "rapports de bugs"... ce sont des extrait de code n'est joindre deux cordes avec un slash sans dupliquer une barre oblique entre eux. C'est tout. Pas plus, pas moins. Il n'évalue pas les chemins d'accès sur le disque dur ni ne fait garder le début d'une barre oblique (ajouter qu'en cas de besoin, au moins vous pouvez être sûr que ce code renvoie toujours une chaîne de caractères sans départ slash).

join('/', array(trim("abc/de/", '/'), trim("/fg/x.php", '/')));

Le résultat final sera toujours un chemin sans slash au début ou à la fin et pas de doubles barres obliques à l'intérieur. N'hésitez pas à faire une fonction de cela.

EDIT: Voici une belle flexible en fonction de l'enveloppe pour extrait ci-dessus. Vous pouvez passer autant de chemin de fragments de code que vous voulez, que ce soit sous forme de tableau ou de séparer les arguments:

function joinPaths() {
    $args = func_get_args();
    $paths = array();
    foreach ($args as $arg) {
        $paths = array_merge($paths, (array)$arg);
    }

    $paths = array_map(create_function('$p', 'return trim($p, "/");'), $paths);
    $paths = array_filter($paths);
    return join('/', $paths);
}

echo joinPaths(array('my/path', 'is', '/an/array'));
//or
echo joinPaths('my/paths/', '/are/', 'a/r/g/u/m/e/n/t/s/');

:o)

17voto

David Miller Points 1245

La fonction de @ deceze ne garde pas la position de tête / lorsque vous essayez de rejoindre un chemin qui commence par un chemin absolu Unix, par exemple joinPaths('/var/www', '/vhosts/site'); .

 function unix_path() {
  $args = func_get_args();
  $paths = array();

  foreach($args as $arg) {
    $paths = array_merge($paths, (array)$arg);
  }

  foreach($paths as &$path) {
    $path = trim($path, '/');
  }

  if (substr($args[0], 0, 1) == '/') {
    $paths[0] = '/' . $paths[0];
  }

  return join('/', $paths);
}
 

16voto

Mark Points 49079

Ma prise

 function trimds($s) {
    return rtrim($s,DIRECTORY_SEPARATOR);
}

function joinpaths() {
    return implode(DIRECTORY_SEPARATOR, array_map('trimds', func_get_args()));
}
 

J'aurais utilisé une fonction anonyme pour trimds , mais les anciennes versions de PHP ne la prennent pas en charge.

Exemple:

 join_paths('a','\\b','/c','d/','/e/','f.jpg'); // a\b\c\d\e\f.jpg (on Windows)
 

Mise à jour avril 2013 Mars 2014 :

 function join_paths() {
    return preg_replace('~[/\\\]+~', DIRECTORY_SEPARATOR, implode(DIRECTORY_SEPARATOR, func_get_args()));
}
 

Celui-ci corrigera les barres obliques pour qu'elles correspondent à votre système d'exploitation, ne supprimera pas les barres obliques, et nettoyera et plusieurs barres obliques à la suite.

4voto

Chris J Points 2581

Une alternative consiste à utiliser implode() et explode() .

 $a = '/a/bc/def/';
$b = '/q/rs/tuv/path.xml';

$path = implode('/',array_filter(explode('/', $a . $b)));

echo $path;  // -> a/bc/def/q/rs/tuv/path.xml
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X