Wie verbinde ich Dateisystempfadzeichenfolgen in PHP?

Lesezeit: 8 Minuten

Benutzer-Avatar
Benutzer89021

Gibt es eine eingebaute Funktion in PHP, um Pfadzeichenfolgen intelligent zu verbinden? Die Funktion, gegeben abc/de/ und /fg/x.php als Argumente zurückgeben sollten abc/de/fg/x.php; das gleiche Ergebnis sollte mit gegeben werden abc/de und fg/x.php als Argumente für diese Funktion.

Wenn nicht, gibt es eine verfügbare Klasse? Es könnte auch nützlich sein, um Pfade aufzuteilen oder Teile davon zu entfernen. Wenn Sie etwas geschrieben haben, können Sie Ihren Code hier teilen?

Es ist in Ordnung, immer zu verwenden /ich codiere nur für Linux.

In Python gibt es os.path.joinwas toll ist.

  • Beachten Sie, dass Ihr Beispiel da ziemlich irreführend ist os.path.join('some/relative/path, '/an/absolute/path') wird immer wiederkommen /an/absolute/path. Sie suchen also entweder nach einem os.path.join Ersatz (korrigieren Sie dann Ihr Beispiel) oder etwas, das ihm nahe kommt, mit der Ausnahme, dass absolute Pfade, die an zweiter Stelle (oder n-ter Stelle) stehen, als relative Pfade behandelt werden.

    Benutzer948581

    24. Februar 2014 um 10:59 Uhr


  • @Tibo und die Befürworter seines Kommentars: Nein, das Beispiel ist überhaupt nicht irreführend, außer wenn man den Kern der Frage ignoriert und darauf besteht, die Python-Referenz zu überbetonen, was eine Randbemerkung zur Orientierung ist. Die Frage ist vollkommen klar, was es will, nämlich nicht exakt os.path.join. Lesen Sie: „Die Funktion, gegeben abc/de/ und /fg/x.php als Argumente zurückgeben sollten abc/de/fg/x.php“.

    – Gr.

    22. Dezember 2017 um 23:17 Uhr


Benutzer-Avatar
Riccardo Galli

function join_paths() {
    $paths = array();

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

    return preg_replace('#/+#',"https://stackoverflow.com/",join("https://stackoverflow.com/", $paths));
}

Meine Lösung ist einfacher und ähnelt eher der Funktionsweise von Python os.path.join

Betrachten Sie diese Testfälle

array               my version    @deceze      @david_miller    @mark

['','']             ''            ''           "https://stackoverflow.com/"              "https://stackoverflow.com/"
['',"https://stackoverflow.com/"]            "https://stackoverflow.com/"           ''           "https://stackoverflow.com/"              "https://stackoverflow.com/"
["https://stackoverflow.com/",'a']           '/a'          'a'          '//a'            '/a'
["https://stackoverflow.com/",'/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'

  • Dies ist die beste Antwort, da sie am besten zur Frage passt – sie kommt ihr am nächsten os.path.join und tut Pfadzeichenfolgen intelligent verbinden. Die Antwort könnte verbessert werden, indem die “Referenz” -Implementierung von hinzugefügt wird os.path.joinund Angabe der spezifischen OPs, die gegen die Regel verstoßen (Testfall ['abc','/def'] ist falsch bzgl os.path.joinaber richtig gemäß der Frage).

    Benutzer948581

    24. Februar 2014 um 10:55 Uhr

  • @qix warum? Windows versteht Schrägstriche ganz gut

    – Riccardo Galli

    12. Dezember 2014 um 9:19 Uhr

  • @qix schau, ich verstehe deinen Punkt, normalerweise würde ich dir zustimmen, aber realistischerweise wird PHP in absehbarer Zeit nicht auf Plattformen laufen, die keine Schrägstriche als Pfadtrennzeichen verwenden, und um die Konstante preg_replace() zu verwenden würde ein echtes Durcheinander werden (Sie müssten dem Pfadtrennzeichen in der Regexp entkommen), also wähle ich diesen Kompromiss.

    – Riccardo Galli

    14. Dezember 2014 um 20:46 Uhr

  • Sie sparen also, weil Sie faul sind, obwohl die String-Interpolation von Konstanten in PHP fast kostenlos ist? Tsk.

    – Qix – MONICA WURDE MISSHANDELT

    14. Dezember 2014 um 22:06 Uhr

  • Als Anmerkung, mein Team hat gerade einen Fall gefunden, wo / Trennzeichen funktionieren nicht (eine alte PHP5.3.4-Installation auf einem Windows Server 2012 mit der msys-Git-Shell).

    – Félix Saparelli

    19. Mai 2015 um 4:47 Uhr

Benutzer-Avatar
verzeihen

Da dies eine beliebte Frage zu sein scheint und die Kommentare sich mit „Vorschlägen zu Funktionen“ oder „Fehlermeldungen“ füllen … Alles, was dieses Code-Snippet tut, ist, zwei Zeichenfolgen mit einem Schrägstrich zu verbinden, ohne Schrägstriche zwischen ihnen zu duplizieren. Das ist alles. Nicht mehr und nicht weniger. Es wertet weder die tatsächlichen Pfade auf der Festplatte aus noch behält es den Schrägstrich am Anfang bei (fügen Sie diesen bei Bedarf wieder hinzu, zumindest können Sie sicher sein, dass dieser Code immer eine Zeichenfolge zurückgibt ohne beginnender Schrägstrich).

join("https://stackoverflow.com/", array(trim("abc/de/", "https://stackoverflow.com/"), trim("/fg/x.php", "https://stackoverflow.com/")));

Das Endergebnis ist immer ein Pfad ohne Schrägstriche am Anfang oder Ende und ohne doppelte Schrägstriche darin. Fühlen Sie sich frei, eine Funktion daraus zu machen.

BEARBEITEN: Hier ist ein netter flexibler Funktionswrapper für das obige Snippet. Sie können beliebig viele Pfadausschnitte übergeben, entweder als Array oder als separate Argumente:

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, "https://stackoverflow.com/");'), $paths);
    $paths = array_filter($paths);
    return join("https://stackoverflow.com/", $paths);
}

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

:Ö)

  • function pj($a,$b) { return rtrim($a, ‘/’) .’/’. ltrim($b, ‘/’); }

    – Benutzer89021

    7. Juli 2009 um 9:52 Uhr

  • Das funktioniert nicht immer wie beschrieben. joinPaths(”, ‘foo.jpg’) wird zu ‘/foo.jpg’. Ich bemerkte dies, nachdem mein PHP-Dateimanager anfing, vom Benutzer hochgeladene Dateien in das Stammverzeichnis des Dateisystems zu schreiben! Eine korrigierte Version sollte alle Pfade entfernen, die leere Zeichenfolgen sind.

    – EricP

    3. Januar 2011 um 3:21 Uhr


  • Sollte dies DIRECTORY_SEPARATOR anstelle von ‘/’ verwenden?

    – David

    13. Januar 2012 um 20:10 Uhr

  • @fe_ Das ist eine völlig andere Funktion als die Frage.

    – verzeihen

    24. Mai 2013 um 13:16 Uhr

  • Ich stimme nicht zu, da die Person eindeutig mitgeteilt hat, dass sie Ergebnisse von Python verwendet hat os.path.join die dieses Ergebnis liefert und die er toll findet. Also ich glaube nicht, dass es eine andere Funktion ist. Genauso wie join('/a/b','../c') sollte zurückkehren /a/c ohne dass eine externe Normalisierung erforderlich ist.

    – fe_lix_

    24. Mai 2013 um 14:04 Uhr


Benutzer-Avatar
David Müller

Die Funktion von @deceze behält das führende / nicht bei, wenn versucht wird, einem Pfad beizutreten, der mit einem absoluten Unix-Pfad beginnt, z 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, "https://stackoverflow.com/");
  }

  if (substr($args[0], 0, 1) == "https://stackoverflow.com/") {
    $paths[0] = "https://stackoverflow.com/" . $paths[0];
  }

  return join("https://stackoverflow.com/", $paths);
}

Benutzer-Avatar
mpen

Meine Einstellung:

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

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

Ich hätte eine anonyme Funktion für verwendet trimdsaber ältere Versionen von PHP unterstützen es nicht.

Beispiel:

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

Aktualisiert April 2013 Marz 2014 Mai 2018:

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

Dieser korrigiert alle Schrägstriche, um sie an Ihr Betriebssystem anzupassen, entfernt keinen führenden Schrägstrich und bereinigt mehrere Schrägstriche hintereinander.

Benutzer-Avatar
Georg Lund

Wenn Sie wissen, dass die Datei/das Verzeichnis existiertSie können zusätzliche Schrägstriche hinzufügen (die möglicherweise unnötig sind) und dann aufrufen realpathdh

realpath(join("https://stackoverflow.com/", $parts));

Das ist natürlich nicht ganz dasselbe wie die Python-Version, aber in vielen Fällen kann es gut genug sein.

Als lustiges Projekt habe ich noch eine weitere Lösung erstellt. Sollte universell für alle Betriebssysteme sein.

Für PHP 7.2+:

<?php

/**
 * Join string into a single URL string.
 *
 * @param string $parts,... The parts of the URL to join.
 * @return string The URL string.
 */
function join_paths(...$parts) {
    if (sizeof($parts) === 0) return '';
    $prefix = ($parts[0] === DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : '';
    $processed = array_filter(array_map(function ($part) {
        return rtrim($part, DIRECTORY_SEPARATOR);
    }, $parts), function ($part) {
        return !empty($part);
    });
    return $prefix . implode(DIRECTORY_SEPARATOR, $processed);
}

Für PHP-Version vor 7.2:

/**
 * Join string into a single URL string.
 *
 * @param string $parts,... The parts of the URL to join.
 * @return string The URL string.
 */
function join_paths() {
    $parts = func_get_args();
    if (sizeof($parts) === 0) return '';
    $prefix = ($parts[0] === DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : '';
    $processed = array_filter(array_map(function ($part) {
        return rtrim($part, DIRECTORY_SEPARATOR);
    }, $parts), function ($part) {
        return !empty($part);
    });
    return $prefix . implode(DIRECTORY_SEPARATOR, $processed);
}

Einige Testfälle für sein Verhalten.

// relative paths
var_dump(join_paths('hello/', 'world'));
var_dump(join_paths('hello', 'world'));
var_dump(join_paths('hello', '', 'world'));
var_dump(join_paths('', 'hello/world'));
echo "\n";

// absolute paths
var_dump(join_paths('/hello/', 'world'));
var_dump(join_paths('/hello', 'world'));
var_dump(join_paths('/hello/', '', 'world'));
var_dump(join_paths('/hello', '', 'world'));
var_dump(join_paths('', '/hello/world'));
var_dump(join_paths("https://stackoverflow.com/", 'hello/world'));

Ergebnisse:

string(11) "hello/world"
string(11) "hello/world"
string(11) "hello/world"
string(11) "hello/world"

string(12) "/hello/world"
string(12) "/hello/world"
string(12) "/hello/world"
string(12) "/hello/world"
string(12) "/hello/world"
string(12) "/hello/world"

Aktualisieren: Eine Version hinzugefügt, die PHP vor 7.2 unterstützt.

Benutzer-Avatar
apaderno

Eine Alternative ist die Verwendung implode() und explode().

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

$path = implode("https://stackoverflow.com/",array_filter(explode("https://stackoverflow.com/", $a . $b)));

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

  • Versuchen Sie es mit der URL /offset/0/limit/1.

    – Danon

    4. Mai 2017 um 11:39 Uhr

1352860cookie-checkWie verbinde ich Dateisystempfadzeichenfolgen in PHP?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy