2009-01-20 25 views
46

Bazı dosyaları PDF'ye dönüştürmem ve sonra bunları bir e-postaya eklemem gerekiyor. E-posta tarafı için Pear Mail kullanıyorum ve bu iyi (çoğunlukla - bazı sorunlar üzerinde çalışıyor) ama bunun bir parçası olarak geçici dosyalar oluşturmam gerekiyor. Şimdi tempnam() işlevini kullanabilirim ama dosya sistemindeki bir dosya oluşturmuş gibi geliyor, istediğim bu değil.PHP'de benzersiz ve geçici dosya adları?

Sadece geçici dosya sisteminde (sys_get_temp_dir() kullanarak), aynı kullanıcının komut dosyasını birden çok kez çağırırken aynı komut dosyasını çalıştıran biriyle çakışmayan bir ad istiyorum.

Öneriler?

cevap

122

Benzersiz bir dosya adı oluşturmak için geçmişte uniqid() kullanmıştım, ancak aslında dosyayı oluşturmuyordum.

$filename = uniqid(rand(), true) . '.pdf'; 

Birinci parametre istediğiniz herhangi bir şey olabilir, ama ben bile biraz daha rasgele hale getirmek için() burada rand kullandı. Ayarlanmış bir önek kullanarak, sistemdeki diğer geçici dosyalar ile çakışmaları önleyebilirsiniz.

$filename = uniqid('MyApp', true) . '.pdf'; 

Buradan dosyayı oluşturursunuz. Eğer her şey başarısız olursa, onu bir süre döngüsüne koyun ve işe yarayana sahip olana kadar üretmeye devam edin.

while (true) { 
$filename = uniqid('MyApp', true) . '.pdf'; 
if (!file_exists(sys_get_temp_dir() . $filename)) break; 
} 
+29

+1; – RobertPitt

+4

Unimquid üzerindeki ilk parametre için rastgele bir sayı kullanmayı seviyorum, ancak bunun yerine hızı nedeniyle mt_rand() kullanıyorum. while döngüsünün kullanıldığı yerler gibi birçok dosya için yararlı olacaktır. –

+0

Bir rand() eklemenin mutlaka bunu yapıp yapamayacağını bilmiyorum * daha * rasgele - oranlar hem sisteme göre hem de rand() tarafından ekiliyor. –

3

Benzersiz bir dosya adı oluşturmak için tarih ve saatin bir bölümünü kullanabilirsiniz, bu şekilde birden çok kez çağrıldığında çoğaltılamaz.

+9

GERÇEKTEN meşgul değilseniz. –

-1

Ben PHP fonksiyonunu kullanmak tavsiye http://www.php.net/tempnam

$file=tempnam('tmpdownload', 'Ergebnis_'.date(Y.m.d).'_').'.pdf'; 
echo $file; 
/var/www/html/tmpdownload/Ergebnis_20071004_Xbn6PY.pdf 

Ya http://www.php.net/tmpfile

<?php 
$temp = tmpfile(); 
fwrite($temp, "writing to tempfile"); 
fseek($temp, 0); 
echo fread($temp, 1024); 
fclose($temp); // this removes the file 
?> 
+0

Bu işe yaramaz, çünkü tempnam ör. AbCdEf dosyasının bulunmadığını ve dolayısıyla bu adı döndürdüğünü tespit edin. Ama .pdf eklersiniz ve zaten AbCdEf.pdf dosyası olabilir (hangi tempnam tespit edemedi) – k3a

+0

Bu yanlış. Tempnam() aslında dosyayı oluşturur ve OP bunu tempnam kullanmamanın nedeni olarak belirtmiştir. Oluşturduğunuz dosya, aradığınız dosya olmayacağından (dosya xyz oluşturulur, xyz.pdf dosyasını arıyor olursanız) çözüm başarısız olur. – crafter

-1
function gen_filename($dir) { 
    if ([email protected]_dir($dir)) { 
     @mkdir($dir, 0777, true); 
    } 
    $filename = uniqid('MyApp.', true).".pdf"; 
    if (@is_file($dir."/".$filename)) { 
     return $this->gen_filename($dir); 
    } 
    return $filename; 
} 
11

Ciddi, kullanım tempnam(). Evet, bu dosyayı oluşturur, ancak bu, sisteminizdeki başka bir işlemi dosya adınızı "çalmaktan" ve işleminizin istemediğiniz dosyaların üzerine yazmasını engellemek için tasarlanmış çok kasıtlı bir güvenlik önlemidir.

, bu sırayı dikkate yani:

  • Sen rasgele isim üretir.
  • Var olmadığından emin olmak için dosya sistemini kontrol edersiniz. Eğer varsa, önceki adımı tekrarlayın.
  • Başka bir kötülük, süreç, Bay Evil'in yanlışlıkla üzerine yazmanızı istediği bir dosyayla aynı adı taşıyan bir dosya oluşturur.
  • Dosyayı, yazma kipinde varolan birini açmak yerine dosyayı oluşturduğunuza ve yazmaya başladığınızı düşünerek açarsınız.
  • Sadece önemli bir şeyin üzerine yazmışsınız.

PHP'nin tempnam() aslında sistemin mkstempini başlık altında çağırıyor (Linux için ...Götürmezse dosyaları kaldırarak başkalarının engelleyen bir dizinin içinin, bir dosya adı

  • kısıtlayıcı izinleri olan dosya oluşturma Seçim

    • : Böyle bir süreçten geçerek diğer işletim için "en iyi uygulama" işlevini), yerine 't ait (bu, yapışkan-bit'in/var/tmp ve/tmp üzerinde yaptığı şeydir)
    • Oluşturulan dosyanın kısıtlayıcı izinlere sahip olduğunu doğrular.
    • Yukarıdakilerden herhangi biri başarısız olursa, farklı bir adla tekrar deneyin.
    • Oluşturulan dosya adını döndürür.

    Şimdi, bu şeyler kendiniz tüm, ama neden, "uygun işlev" güvenli geçici dosyaları oluşturmak için gerekli olan minimum ve bu hemen hemen her zaman sizin için boş bir dosya yaratma içerir şeyi yaptığında.

    İstisnalar:.

    • Yalnızca işlem dosyaları silebilir/oluşturabileceğiniz bir dizinde geçici bir dosya oluştururken
    • , rasgele oluşturulmuş bir geçici dizini hangi yalnızca işlem yapabilirsiniz oluşturun dosya oluştur/sil.
  • 0

    Kullanıcı kimliği ile unix zaman damgası kullanırsanız daha iyi.

    max yürütme zamanı yerine çalışma ile @Lusid Yanıta göre

    $filename='file_'.time().'_'.$id.'.jepg';

    2

    diğer alternatif:

    //////////// Max exectution time of 10 seconds. 
    $maxExecTime = time() + 10; 
    $isUnique = false; 
    
    while (time() !== $maxExecTime) { 
        //////////// Unique file name 
        $uniqueFileName = uniqid(mt_rand(), true) . '.pdf'; 
        if (!file_exists(sys_get_temp_dir() . $uniqueFileName)){ 
         $isUnique = true; 
         break; 
        } 
    } 
    
    if($isUnique){ 
        //////////// Save your file with your unique name 
    }else{ 
        //////////// Time limit was exceeded without finding a unique name 
    } 
    

    Not: Ben yerine mt_rand kullanmayı tercih

    rand, çünkü ilk işlev Mersenne Twister algorithm kullanıyor ve ikinci saniyeden daha hızlı (LCG).


    diğer bilgiler:

    0

    Benim fikrim görmek için özyinelemeli işlevi kullanmaktır Dosya adı varsa ve varsa, while döngüsüne bir sonraki tam sayı için yineleyin: while döngüsü için

    İlgili konular