Autor Zpráva
petřík
Profil *
Ahoj,
mám DB do které ukládám nazvy fotek a fotky loaduji na ftp do adresare Foto. Nemám ale ošetřeno že když budu nahrávat fotku která bude mít stejný název jako fotka minule nahraná aby se mi nepřepsala.
Mužete mi prosím poradit jak nejlépe to udělat. Napadlo mě ověřování v DB zda už tam ten název je a pak vypsat hlášku třeba - soubor už existuje. Ale asi by bylo lepší aby se k souboru přidala třeba číslice aby to uživatele neotravovalo.
Jak nejlépe to tedy udělat?
Děkuji
Kcko
Profil
http://www.webfaq.cz/clanek/Jak-v-PHP-ziskat-unikatni-nazev-souboru-ktery-v-adresari-neexistuje
petřík
Profil *
Pročetl jsem si návod a zkouším ho zařadit do mého scriptu. Mám script pro nahrání více souboru. Funguje mi to ale pouze když nahrávám jeden soubor, jakmile jich chi nahát víc tak mi vyjede tato chyba:
Fatal error: Cannot redeclare class File in C:\wamp\www\www\administrace\zadej_foto.php on line 66 (řadek class File {)

Prosím o radu jak to zprovoznit i pro více souborů. Děkuji


for($i = 0; $i < count($_FILES['foto']['tmp_name']); $i++)
                            {  
                                  echo $_FILES['foto']['tmp_name'][$i], " ", $_FILES['foto']['name'][$i], "<br>";
                                  if (is_uploaded_file($_FILES['foto']['tmp_name'][$i]))
                                    {
                                     echo $_FILES['foto']['tmp_name'][$i], " ", $_FILES['foto']['name'][$i], "<br>";  
                                     class File {
                                                	public function __construct() { }	
                                                	public static function getOriginalName($path, $file) 
                                                          {
                                                		$i=0;
                                                		while (file_exists($path.$file)) 
                                                                                    {
                                                			$pos = strrpos($file, ".");
                                                			$ext = strtolower(substr($file , $pos+1));
                                                			if (preg_match("/.+-CID(\d+)\.[a-zA-Z]{3,4}$/", $file)) 
                                                			      {
                                                				$file = preg_replace("/(.+)(-CID\d+)(\.[a-zA-Z]{3,4}$)/", "$1-CID".$i, $file);
                                                			       } 
                                                			elseif (preg_match("/.+(\.)[a-zA-Z]{3,4}$/", $file)) 
                                                			      {
                                                				$file = preg_replace("/(.+)(\.[a-zA-Z]{3,4})$/", "$1-CID".$i, $file);
                                                        			       }
                                                	                      else  {
                                                		              $file = "FILE-CID".$i.".".$ext;
                                                	          	               }
                                                	    	       $i++;
                                                		       $file = $file.".".$ext;
                                                		     }
                                                		return $file;		
                                               	         }	
                                                 }  
                                       $file = $_FILES['foto']['name'][$i]; 
                                       $file = File::getOriginalName("../foto/", $file);
                                       $uploaddir = '../foto/'; 
                                       $uploadfile = $uploaddir . $file;
                                       $name = $_FILES['foto']['name'][$i];
 
                                       if (move_uploaded_file($_FILES['foto']['tmp_name'][$i], $uploadfile)) 
                                          {
                                           
                                           $vysledek=mysql_query("insert into foto (cas, foto) values (".time().",'".$file."')");
                                          } 
                                       else 
                                          { 
                                           nepovedlo
                                           }   
                                      }
                                    } 
Keeehi
Profil
petřík:
přejmenujte třídu File třeba na HCHKRDTN nebo AEIOUI, prostě aby se netřískala s jinou třídou File.

PS. PHP asi taky nebude nadšeno z řádku 46 v tomto kódě.
imploder
Profil
petřík:
Ten kód je potenciálně nebezpečný: může se stát, že jiný běžící PHP skript soubor vytvoří v době mezi tím, kdy tenhle skript zjistí, že je jméno volné a dobou, kdy takový soubor opravdu bude vytvořen - tzn. může se stát, že v určitém okamžiku budou dva skripty považovat stejný soubor za neexistující a oba se ho pokusí vytvořit, takže dojde ke kolizi. Jinými slovy, tohle řešení není tzv. thread-safe.

Možné řešení je vytvořit soubor funkcí tempnam, ta je thread-safe, ke kolizi s ní dojít nemůže.
petřík
Profil *
imploder:
Mužeš mi to prosím tě vysvětlit blíže jak jím mám použít?
petřík
Profil *
Keeehi:
řadek 46 je jasný chybí echo, ale tva rada s přejmenováním nepomohla. když to přepišu třeba na hkl tak to vyhodí chybu:
Fatal error: Cannot redeclare class hkl in C:\wamp\www\administrace\zadej_foto.php on line 66
Keeehi
Profil
petřík:
Omlouvám se. Myslel jsem, že je chyba trochu jinde. Jmenovat se (nejspíše) může pořád File. Co je ale potřeba udělat je, vyhodit ji mimo ten cyklus. Takže řádky 7-32 přesuňte před 1. řádek.
petřík
Profil *
Keeehi:
Jo super to je ono.. A co si myslíš ty o tom co psal imploder, měl bych to tedy řešit nějak jinak?
Keeehi
Profil
petřík:
Myslel tím to, že pokud by se script spustil 2x přibližně v hodně podobný čas, mohl by nastat problém.
vlákno 1 - Existuje soubor "soubor.txt"? Ne
vlákno 2 - Existuje soubor "soubor.txt"? NE
vlákno 1 - Vytvoř "soubor.txt" - OK
vlákno 2 - Vytvoř "soubor.txt" - nastává problém, soubor už existuje

- jinak řečeno: V době mezi zjištěním existence souboru a jeho vytvořením, si stihne jiné spuštění toho samého scriptu zeptat na to samé. Nemusí ale vždy "zkolabovat" to druhé spuštění. Provádění toho prvního scriptu může být pozastaveno před vytvořením toho souboru protože to druhé spuštění bude mít větší prioritu.

Takže imploder ti radí použít funkci tempnam(), protože u ní takový problém nehrozí. "Nemůže se do ní nic vmáčknout a rozbít ji."
imploder
Profil
petřík:
Mužeš mi to prosím tě vysvětlit blíže jak jím mám použít?
Úplně normálně, nic zvláštního s ní dělat nemusíš. Viz manuál: http://php.net/manual/en/function.tempnam.php

$jmeno = tempnam('/muj/adresar', 'mujsoubor_');
if ($jmeno === FALSE) 
  echo "nepodarilo se vytvorit soubor";
else
  echo "jmeno souboru: $jmeno";
petřík
Profil *
imploder:
A to tu svoji funkci class File mám úpně vyhodit a nahradit to mejak timto:

$jmeno = tempnam('../foto', $file);
if ($jmeno === FALSE) 
  echo "nepodarilo se vytvorit soubor";
else
  echo "jmeno souboru: $jmeno";


Stejně tam ale přeci někde musím mít tu změnu souboru ne?
imploder
Profil
petřík:
Ta funkce vytvoří soubor, který tam ještě není a vrátí jeho jméno. Do toho souboru pak úplně normálním způsobem uložíš fotku. Co na tom nechápeš?
petřík
Profil *
A na základě čeho vytvoří název toho souboru. To jako že nejprve zkontroluje podle toho prvního řádku zda tam ten soubor je a nějak ho změní?
A nebo místo toho echo "nepodarilo se vytvorit soubor"; potřebuji nějakou funkci na jeho změnu jako jsem měl v tom prvím kódu?
imploder
Profil
petřík:
A na základě čeho vytvoří název toho souboru.
Vymyslí si ho náhodně a takový, aby se neshodoval s žádným, co už v tom adresáři (1. parametr) je; jisté je, že bude akorát začínat zadaným prefixem (2. parametr).

Ta funkce prostě vytvoří soubor a vrátí název toho vytvořeného souboru. Když se nepodaří soubor vytvořit, vrátí NULL. Jestli ti dělá problém tohle pochopit, tak se jdi nejdřív naučit základy PHP.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: