Jak v PHP získat unikátní název souboru, který v adresáři neexistuje

Článek je další rozšíření knihovny File, který řeší snadné nalezení unikátního (originálního) jména souboru v dané cestě a vrací nový název souboru.


Zdrojový kód ke stažení example17.zip

V rámci tohoto serveru a tipů, zde uvedených je postupně uvolňována knihovna File, která zahrnuje běžné operace potřebné pro práci se soubory. Předchozí díl řešil otázku: Jak nabídnou soubor ke stažení.

Tento díl řeší jak nalézt v daném adresáři unikátní název souboru.

  1. <?
  2. class File {
  3. public function __construct() { }   
  4. public static function getOriginalName($path, $file) {
  5. $i=0;
  6. while (file_exists($path.$file)) {
  7. $pos = strrpos($file, ".");
  8. $ext = strtolower(substr($file , $pos+1));
  9. if (preg_match("/.+-CID(d+).[a-zA-Z]{3,4}$/", $file)) {
  10. $file = preg_replace("/(.+)(-CIDd+)(.[a-zA-Z]{3,4}$)/", "$1-CID".$i, $file);
  11. } elseif (preg_match("/.+(.)[a-zA-Z]{3,4}$/", $file)) {
  12. $file = preg_replace("/(.+)(.[a-zA-Z]{3,4})$/", "$1-CID".$i, $file);
  13. } else {
  14. $file = "FILE-CID".$i.".".$ext;
  15. }
  16. $i++;
  17. $file = $file.".".$ext;
  18. }
  19. return $file;
  20. }
  21. }
  22. ?>

Skript rozdělí soubor na název a jeho příponu, vyzkouší zda v dané cestě existuje, pokud ano, přidá nakonec text CID a pořadové číslo, tento cyklus pokračuje tak dlouho dokud není nalezen unikátní název souboru, který je funkcí vrácen.

Celá funkce v rámci třídy se dá používat voláním File::getOriginalName("../cesta/", "unikatnisoubor.txt");.

komentáře

RSS Komentáře k článku RSS Komentáře   Add to Google
31.05.2008 18:08 | Anonym (Watchick) | $file

Zdravím mám dotaz, co má být na začátku a na konci ve $file?

31.05.2008 23:06 | Administrátor | Re: $file
  1. na začátku – na vstupu funkce je název souboru, který chci uložit
  2. výstupem je název souboru, který v adresáři neexistuje, název se vytváří přidáním textu -CID1, -CID2, -CID3 atd.
01.06.2008 17:14 | Anonym (Kcko) | Zajimave

A proste generovani

$nazev_souboru + salt ( time(), uniqid()) atd .. by to nevyresilo taky? :)

02.06.2008 12:38 | Administrátor | Re: Zajimave

určitě vyřešilo, ale kdo se v tom má vyznat soubor.png soubor157846911­3.png soubor154646511­3.png soubor157979911­3.png

nebo

soubor.png soubor-CID1.png soubor-CID2.png soubor-CID3.png

myslím tím, když někdo obrázek stahuje, nebo na serveru vybíráš příslušný obrázek, tak salt (timestamp atd, nic neřekne), každopádně ať každý používá co mu vyhovuje :) tohle je jen návrh jak to dělám já

01.06.2008 20:29 | Anonym (v6ak) | přímo v php?

PHP na to má AFAIK přímo nějakou fci.

02.06.2008 12:32 | Administrátor | Re: přímo v php?

napiš jakou o žádné nevím, ale je to možné

03.06.2008 10:59 | Anonym (Kcko) | Chyba

Tak nejak nevim kolego, ale toto volani

$file = ‚test.txt‘;
$file = File::getOrigi­nalName('', $file);
file_put_conten­ts($file, date(‚h:i:s‘));

Mi vytvari soubory typu

test-CID0-CID1.png test-CID0-CID1-CID2.png

Vecer se na to doma v klidu podivam a zkusim to opravit

03.06.2008 10:59 | Anonym (Kcko) | Oprava

$file = ‚test.tx ⇒ $file = 'test.png‘

03.06.2008 18:19 | Administrátor | Re: Oprava

nějak mi není jasné jak z text.txt může vylézt test.png, kde by se to png vzalo?

03.06.2008 18:21 | Anonym (Kcko) | Re: Re: Oprava

Jasne to jsem spatne zkopiroval

Jak rikam tento kod

$file = ‚test.png‘; $file = File::getOrigi­nalName('', $file); file_put_conten­ts($file, date(‚h:i:s‘));

a pote F5 ( nekolikrat ) a vytvari mi soubory

test-CID0-CID1.png test-CID0-CID1-CID2.png test-CID0-CID1-CID2-CID3.png

Diky

03.06.2008 18:33 | Administrátor | Re: Re: Re: Oprava

nemůžu si pomoct, ale bez problému mi to funguje, přidal jsem zdrojový kód ke stažení pro ukázku toho co používám

03.06.2008 15:21 | Anonym (Kcko) | Nedalo by mi ,, sestavil jsem si vlastni kod

[code] class File {
public function __construct()
{

}

public static function getExtension($file)
{
preg_match(„~(­.+).(.+)~“, $file, $out);
return $out[2];
}

public static function getHoleFilena­me($file)
{
preg_match(„~(­.+).(.+)~“, $file, $out);

return $out[1];
}

public static function getOriginalNa­me($file = '', $path = '')
{
$orig_file = $file;

if (!is_file($path . $file))
return $file;

$i = 0;
do
{
$file = self::getHole­Filename($orig_fi­le) . ‚-CID‘ . $i . ‚.‘ . self::getExten­sion($file);
$i++;

}
while(is_file($path . $file));

return $file;
} } [/code]

A porad nejak nevim kde je u Tebe chyba, ale kdyz to napises rad se na to podivam

03.06.2008 18:12 | Administrátor | Re: Nedalo by mi ,, sestavil jsem si vlastni kod

mě to funguje, už roky, nemám možnost to teď vyzoušet, ale pokusím se zkontrolovat jestli jsem neudělal chybu v přepisu toho kódu

03.06.2008 18:21 | Administrátor | Re: Re: Nedalo by mi ,, sestavil jsem si vlastni kod

pravda je, že když na to koukám původně to bylo určené pro obrázky a celý regulární výraz je napsaný pro soubory s 3 písmeny v příponě, tam by snad mohla být chyba!

22.01.2009 15:35 | Anonym (Jakub Vrána) | Atomicita operací

Kód nerespektuje fakt, že jeden skript může být v prostředí webové aplikace spuštěn paralelně vícekrát. Viz http://php.vrana.cz/…-operaci.php

PHP funkce tempnam() tento fakt respektuje.

24.01.2009 01:40 | Administrátor | Re: Atomicita operací

díky za upozornění na tempnam, ale tam mi vadí právě ta náhodnost toho unikátu, tedy že se v takových souborech velice těžko orientuje, co se týče atomicity tak souhlasím, jen kdyby to šlo řešit tak, aby jednotlivé unikáty měli nějaký řád

Jméno
Název
Text
Lze používat Texy! syntax. Příklad syntaxe: "text odkazu":odkaz, **tučně**, *kurzíva*, `code`. PHP kód uzavírejte do <?php ... ?> a JavaScript do <script> ... </script>