Çarpışan yüklenenler için PHP geçici dosya adları

5 Cevap php

Bir kullanıcı rastgele başka bir kullanıcının yüklenme yerini alır bir dosyayı yüklediği zaman, ben nihayet PHP sorunu izini ettik ve tmp dosya adı yeniden ediliyor. Bunu düzeltmek için bir yolu var mı? Daha rasgele isim yapmak için bir yolu var mı? Rasgele dosya adı tohum zayıflar gibi, zamanla bozulduğundan görünüyor? Bu PHP 5.2.8 ve FreeBSD 7.0 üzerinde

Burada aynı tmp dosya adı alışmakta nasıl gösteren bir günlük olduğunu ve başka bir yüklenme ile yazılır: http://pastebin.com/m65790440

Herhangi bir yardım büyük beğeni topluyor. Ben 4 ay boyunca bu düzeltmek için çalışıyor ettik ve zaman içinde daha da kötüleşti. Teşekkür ederim.

EDIT: Bu herhangi bir PHP kodu ulaşmadan önce, bu oluyor, bir PHP kodu sorun olmadığını aklınızda tutun, dosya $ HTTP_POST_FILES ['name'] ['tmp_name'] ile alınan alındığı zaman yanlış ve takip edilmiş Bu yükleme işleme komut ulaşmadan önce o başkasının yüklenme ile yazılır ediliyor geri o

5 Cevap

Bir şey PHP kurulumu ya da hangisi sistem çağrısı PHP ile ya ciddi bir yanlış olduğunu gibi içten rastgele dosya adları oluşturmak için kullanıyor sesleri (büyük olasılıkla tempnam).

Herkes için: PHP kullanıcı kodu önce içten yüklenen dosyaları işleme hiç işlenir. Bu isimler saklanır $_FILES['file']['tmp_name'] ('dosya' formdaki dosya giriş elemanı (alıntı) adıdır).

mod_php olarak PHP, Apache altında çalışıyor?

You may try to create a per-process temporary upload directory whose name contains your php getmypid(), then ini_set your PHP process' upload_tmp_dir to that directory. This will not work if a new php process is spawned for every request.

FreeBSD 7'nin libc uygulanması _gettemp aşağı ilgili kodu kovalayan sonra, dosyanın içeriğini tmp_name geçersiz olabileceğini nasıl ilgili şüphelerim var. (Onu izlemek için, PHP 5.2.8 bir kopyasını indirmek olabilir ve main/rfc1867.c okumak - satır 1018 çağrıları main/php_open_temporary_file.c, işlev hattında 227 başlayan, o ana bir iş yapar, hangi Ancak, {[(0)] kullanır FreeBSD libc implementation hat 66 üzerinde (bağlantılı) bulunan sisteminizde, esasen mkstemp için sadece bir sarıcı hat 97, başlayan işlevinde } (yukarıdaki ile aynı) aslında rastgele dosya oluşturmak için. Ancak the manpage for mkstemp BÖCEK bölümünde bahseder arc4random() function is not reentrant. It might bir olasılık olması 2 eşzamanlı istekleri Kritik kod bölümüne giren ve aynı tmp_name dönüyor - Ben FastCGI / php-cgi kullanarak işe yarayabilecek olsa (Apache orada Yorumlamak için mod_php veya php-cgi biriyle nasıl çalıştığı hakkında çok az şey biliyoruz - I can ' t) Bu zamanda bu başarıyla yorum.

Oldukça dosyayı karşılaşmayan Ancak, simpliest çözüm amaçlayan tmp_name kendisi geçersiz olması, ancak tek kaynağı olarak tmp_name dosya adı kısmını kullanarak eğer, örneğin, (diğer yüklenen dosyalar ile yerine çarpışarak depolanan dosya) teklik, nedeniyle birthday paradox için çarpışmalar karşı karşıya olabilir. In another question taşımak için bazı 5.000.000 dosyaları olan söz, ve still another question Eğer recieving söz 30-40k bir gün yükler. Bu bir doğum günü paradoks çarpışma için önemli bir durum olarak beni vurur. mktemp man page 56800235584 olası dosya adları vardır (PHP yaptığı gibi altı 'Xs' kullanıyorsanız) bahseder (62 ** 6, ya da 62 ** n nerede 'Xs' n = sayı, vb.) Ancak, bazı 5 milyon dosya daha var ki verilen, bir çarpışma olasılığı approximately 100% (başka sezgisel zaten, zaten 220 çarpışmaların bazılarının sırasını yaşamış olacak göstermektedir olan ((dosyaları (* dosyaları eğer -1)) / 2) / (62 ** 6) şey demektir, burada dosyalar = 5,000,000). Bu (olası, if oluşturulan yüklenen dosya için daha fazla entropi eklenirken değil) karşı karşıya sorun varsa, sizin gibi move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.')) şey deneyebilirsiniz - daha fazla rastgelelik eklemek olma fikri rasgele dosya adı, çarpışmaları önleyerek. Alternatif main/php_open_temporary_file.c ve 134 hat ve yeniden derlemek için iki daha 'Xs' eklemek olabilir.

Onlar yüklenen sonra bir kullanıcı dir dosyalarınızı taşıyın. Bu geçici dosyaları çıkarılmalıdır.

Seni o kadar çok alıyorsanız olduğunu görerek dosya için bir GUID jeneratör kullanarak öneriyoruz.