Kombinieren Sie Verzeichnis- und Dateinamen in PHP (entspricht Path.Combine in .Net)

Lesezeit: 6 Minuten

Benutzer-Avatar
Graviton

Dies sollte eine einfache Frage sein, aber ich kann mich einfach nicht an die relevante API erinnern. Eine Suche bei Google mit dem Begriff „Verzeichnisnamen php kombinierenbringt keine Ergebnisse. Ich schätze, ich tue sowohl mir als auch der Programmierer-Community einen Dienst, indem ich diese Frage stelle. Dies ist jetzt der Top-Eintrag, der von Google und DDG zurückgegeben wird!

Wie kombiniert man Verzeichnis- und Dateinamen zu einem vollständigen Dateipfad in PHP? Nehmen wir an, der Verzeichnisname lautet “D:\setup program“, und der Dateiname ist “mj.txt“. Die Methode sollte mich unter Windows zurückgeben “D:\setup program\mj.txt“. Natürlich sollte die Methode den richtigen Dateipfad in Linux oder anderen Betriebssystemen zurückgeben.

Die zugehörige Funktion in .Net ist Pfad.Kombinierenaber in PHP konnte ich mich nicht daran erinnern, obwohl ich es schon einmal gesehen haben muss.

$filepath = $path . DIRECTORY_SEPARATOR . $file;

Obwohl es in neueren PHP-Versionen egal ist, in welche Richtung die Schrägstriche gehen, ist es in Ordnung, immer Schrägstriche zu verwenden.

Sie können einen korrekten absoluten Pfad mit erhalten realpath()entfernt dies auch Dinge wie zusätzliche unnötige Schrägstriche und löst Verweise wie auf ../. Es wird false zurückgegeben, wenn der Pfad nicht gültig ist.

  • Ich glaube nicht, dass PHP, das Schrägstriche unter Windows akzeptiert, irgendetwas mit PHP zu tun hat. Sie können Schrägstriche in neueren Windows-Versionen in der Shell/im Explorer eingeben.

    – Seelenverschmelzung

    26. Juni 2009 um 16:20 Uhr

  • Beachten Sie, dass ” . DIRECTORY_SEPARATOR . ‘foo.txt’ konvertiert einen relativen Pfad in einen absoluten Pfad.

    – EricP

    3. Januar 2011 um 3:17 Uhr

  • Was ist, wenn $file bereits ein absoluter Pfad ist? Path.Combine behandelt dies, aber einfache Zeichenfolgenverkettung nicht.

    – Jojo

    20. März 2012 um 2:18 Uhr

  • Beachten Sie, dass realpath() false zurückgibt, selbst wenn die Datei, auf die der Pfad zeigt, nicht existiert! Sie sollten also nicht realpath() verwenden, wenn Sie dabei sind, die Datei für $filepath zu erstellen.

    Benutzer2443147

    12. Juni 2014 um 20:51 Uhr

  • Dies ist nicht das Äquivalent von .Nets Path.Combine, da „C:\“ und „file.php“ fälschlicherweise als „C:\\file.php“ kombiniert werden.

    – TZubiri

    15. August 2017 um 13:22 Uhr

Ich denke, der sauberste und flexibelste Weg, dies zu tun, wäre die Verwendung der Join-Funktion plus der DIRECTORY_SEPARATOR-Konstante:

$fullPath = join(DIRECTORY_SEPARATOR, array($directoryPath, $fileName));

Alle gegebenen Antworten stoßen nicht auf leere Werte in der $directoryPath und behandeln Sie keine doppelten Schrägstriche. Obwohl es stimmt, dass PHP sehr fehlertolerant ist, kann der erste Punkt fatal sein und der zweite Punkt sollte nicht ignoriert werden, wenn Sie sauberen Code schreiben.

Die richtige Lösung lautet also:

function PathCombine($one, $other, $normalize = true) {

    # normalize
    if($normalize) {
        $one = str_replace("https://stackoverflow.com/", DIRECTORY_SEPARATOR, $one);
        $one = str_replace('\\', DIRECTORY_SEPARATOR, $one);
        $other = str_replace("https://stackoverflow.com/", DIRECTORY_SEPARATOR, $other);
        $other = str_replace('\\', DIRECTORY_SEPARATOR, $other);
    }

    # remove leading/trailing dir separators
    if(!empty($one) && substr($one, -1)==DIRECTORY_SEPARATOR) $one = substr($one, 0, -1);
    if(!empty($other) && substr($other, 0, 1)==DIRECTORY_SEPARATOR) $other = substr($other, 1);

    # return combined path
    if(empty($one)) {
        return $other;
    } elseif(empty($other)) {
        return $one;
    } else {
        return $one.DIRECTORY_SEPARATOR.$other;
    }

}

Einzige Einschränkung ist, dass der zweite Parameter kein absoluter Pfad sein darf.

Benutzer-Avatar
Kantin Charignon

10 Jahre später, aber vielleicht hilft das den nächsten. Folgendes habe ich getan, um es mit PHP 7.4+ kompatibel zu machen.

Es funktioniert genauso wie Path.Combine, außer dass das \ oder / am Anfang der Zeichenfolge die vorherigen Argumente nicht ausschließt.

class Path
{
    public static function combine (): string
    {
        $paths = func_get_args();
        $paths = array_map(fn($path) => str_replace(["\\", "https://stackoverflow.com/"], DIRECTORY_SEPARATOR, $path), $paths);
        $paths = array_map(fn($path) => self::trimPath($path), $paths);
        return implode(DIRECTORY_SEPARATOR, $paths);
    }

    private static function trimPath(string $path): string
    {
        $path = trim($path);
        $start = $path[0] === DIRECTORY_SEPARATOR ? 1 : 0;
        $end = $path[strlen($path) - 1] === DIRECTORY_SEPARATOR ? -1 : strlen($path);
        return substr($path, $start, $end);
    }
}

Path::combine("C:\Program Files", "/Repository", "sub-repository/folder/", "file.txt");
//return "C:\Program Files\Repository\sub-repository\folder\file.txt"

Path::combine("C:\Program Files", "/Repository/", "\\sub-repository\\folder\\", "sub-folder", "file.txt");
//return "C:\Program Files\Repository\sub-repository\folder\sub-folder\file.txt"

Path::combine("C:\file.txt");
//return "C:\file.txt"

Path::combine();
//return ""

Benutzer-Avatar
Zenhai

Sie können es einfach mit der PHP-Konstante verketten DIRECTORY_SEPARATOR, oder verwenden Sie einfach Schrägstriche. Windows wird wahrscheinlich nichts dagegen haben =D

  • Das funktioniert möglicherweise nicht, wenn $folderPath mit ‘/’ endet – der generierte Pfad wäre also “/var/somepath//fileName”.

    – Dai

    18. November 2011 um 0:03 Uhr

  • Eigentlich // funktioniert meistens gut. Zumindest unter Windows und in Bash. Nicht sicher, wo es zu Problemen führen würde.

    – Nux

    5. November 2019 um 16:27 Uhr

Benutzer-Avatar
Benutzer6307854

Dies ist nicht genau das, wonach Sie gesucht haben, aber es sollte ein Array von Pfadteilen erhalten, dann die Teile mit DIRECTORY_SEPARATOR verbinden, dann die verbundenen Teile mit DIRECTORY_SEPARATOR teilen und die leeren Pfadteile entfernen. Es sollte die verbleibenden Pfadteile zurückgeben, die durch DIRECTORY_SEPARATOR verbunden sind.

 function path_combine($paths) {
  for ($i = 0; $i < count($paths); ++$i) {
    $paths[$i] = trim($paths[$i]);
  }

  $dirty_paths = explode(DIRECTORY_SEPARATOR, join(DIRECTORY_SEPARATOR, $paths));
  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $dirty_paths[$i] = trim($dirty_paths[$i]);
  }

  $unslashed_paths = array();

  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $path = $dirty_paths[$i];
    if (strlen($path) == 0) continue;
    array_push($unslashed_paths, $path);
  }

  $first_not_empty_index = 0;
  while(strlen($paths[$first_not_empty_index]) == 0) {
    ++$first_not_empty_index;
  }
  $starts_with_slash = $paths[$first_not_empty_index][0] == DIRECTORY_SEPARATOR;

  return $starts_with_slash
    ? DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $unslashed_paths)
    : join(DIRECTORY_SEPARATOR, $unslashed_paths);
}

Beispielnutzung:

$test = path_combine([' ', '/cosecheamo', 'pizze', '///// 4formaggi', 'GORGONZOLA']);
echo $test;

Wird ausgegeben:

/cosecheamo/pizze/4formaggi/GORGONZOLA

  • Das funktioniert möglicherweise nicht, wenn $folderPath mit ‘/’ endet – der generierte Pfad wäre also “/var/somepath//fileName”.

    – Dai

    18. November 2011 um 0:03 Uhr

  • Eigentlich // funktioniert meistens gut. Zumindest unter Windows und in Bash. Nicht sicher, wo es zu Problemen führen würde.

    – Nux

    5. November 2019 um 16:27 Uhr

Probieren Sie diese Funktion aus. Ich benutze diese Funktion, um meine eigenen Bedürfnisse zu erfüllen.

Wenn Sie den Pfad überprüfen möchten, müssen Sie $isReal auf true setzen

  public static function path($base, $com = null, $isReal = false)
  {
    if(substr($base, -1)!=DIRECTORY_SEPARATOR) $base.=DIRECTORY_SEPARATOR;
    if($com) $base.=$com;
    $base = preg_replace('/(\/+|\\\\+)/', DIRECTORY_SEPARATOR, $base);
    while(preg_match('/(\/[\w\s_-]+\/\.\.)/', $base)){
      $base = preg_replace('/(\/[\w\s_-]+\/\.\.)/', "", $base);
      if(preg_match('/\/\.\.\//', $base))
        throw new \Exception("Error directory don't have parent folder!", 1);
    }
    if($isReal){
      $base = realpath($base);
      if(is_dir($base)) $base .= DIRECTORY_SEPARATOR;
    }
    return $base;
  }

Beispielausgabe:

var_dump(Combine::path("www///system", "Combine/../"));
// string(11) "www/system/"

var_dump(Combine::path("System", "Combine/../", true));
// string(40) "/home/snow/Desktop/localhost/www/System/"

var_dump(Combine::path("System", "Combine", true));
// string(48) "/home/snow/Desktop/localhost/www/System/Combine/"

var_dump(Combine::path("System", "Combine/notPath", true)); // if you try to create a path that does not exist
// bool(false)

var_dump(Combine::path("System", "Combine/class.Combine.php", true)); // you can also select a file
//string(65) "/home/snow/Desktop/localhost/www/System/Combine/class.Combine.php"

var_dump(Combine::path("/home/testuser\\badPath///////repair"));
// string(30) "/home/testuser/badPath/repair/"

1246410cookie-checkKombinieren Sie Verzeichnis- und Dateinamen in PHP (entspricht Path.Combine in .Net)

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

Privacy policy