Autor Zpráva
smiesek
Profil
Ráda bych poprosila o radu s funkcí rename.

Pokud do funkce rename uvedu pouze názvy souborů, původní soubor mi nemizí, ale dočetla jsem se, že se do rename uvádí absolutní cesta, tedy i s adresáři a tedy pak v tomto případě, se mi sice uploadovaný soubor přejmenuje, ale současně se mi smaže z adresáře i soubor, kvůli kterému se to musí přejmenovat.

Přikládám část kodu a budu ráda za pomoc, proč tomu tak je

původní bez adresáře - nechává obsah adresáře
        if(file_exists("downloads/" .$soubor_name)) {
            rename($soubor_name,"x".$soubor_name);
            move_uploaded_file($_FILES['soubor']['tmp_name'], 'downloads/x'.$soubor_name);
            echo "Soubor byl přejmenován";
            exit;
        }

funkce rename s adresářem, kdy např. nahraju soubor text.txt, vše OK, nahraju opět soubor text.txt - ten se přejmenuje na xtext.txt. Na potřetí nahraju soubor text.txt - přejmenuje na xtext.txt, ale zároveň ze složky se smaže soubor text.txt.
        if(file_exists("downloads/" .$soubor_name)) {
            rename("downloads/" .$soubor_name,"downloads/"."x".$soubor_name);
            move_uploaded_file($_FILES['soubor']['tmp_name'], 'downloads/x'.$soubor_name);
            echo "Soubor byl přejmenován";
            exit;
        }
juriad
Profil
smiesek:
To první je blbost. Vždy když pracuješ se soubory musíš uvést cestu, nikoli jen jméno souboru (jak by ta funkce věděla, kde ten soubor má hledat). Někdy však může ta cesta být prázdná, pokud se jedná o soubor v aktuálním adresáři. To, co jsi tam zadala ty je ve skutečnosti relativní adresa; absolutní by musela začínat lomítkem.
V unixovém světě rename nejenom přejmenování soubor, ale i přesouvá. Můžeš si to představit jako přejmenování celé cesty k souboru.

To chování druhého je správné. Přečti si znovu, co jsi napsala.
Pokud takový soubor již existuje, tak ho přejmenuj, tak aby jeho název začínal ikskem.
Přesuň nahraný soubor z tempu do adresáře dowbnloads, tak že jeho název bude začínat ikskem - tedy vidíš tu kolizi.

Bud tedy zahoď 2. řádek, pak starý soubor bude mít pořád stejné jméno,
nebo zruš to iksko na 3. řádku, pak se přejmenuje starý soubor a nový bude mít název jako míval ten starý.
smiesek
Profil
aha, jak si to čtu po sobě, tak je to logické, já jsem právě chtěla předejít tomu, aby se mi v případě stejných názvů, např. jednou budu uploadovat text.txt a po druhé budu taky nevědomě uploadovat text.txt, tak aby se mi to pouze nepřehrálo, ale aby se vytvořila jakoby kopie, proto to rozlišení na x
juriad
Profil
smiesek:
Ale to rozlišení je blbě navržené. Co když nekdo uploadne soubory třeba v pořadí:
xxtext.txt
text.txt
xtext.txt

V realné aplikaci se to řeší tak, že soubory obvykle nemají zachovaný původní název a pojmenují se třeba podle primárního klíče z databáze (vložíš záznam do databáze, dostaneš primární klíč, uložíš soubor s id jako názvem a pak záznam updateneš).
A obvykle pak nedáváš odkaz přímo na soubor, ale na tvůj skript file.php?id=..., který vlastně jen pošle správne hlavičky a následně zavolá readfile. Máš tak k dispozici mnohem větší možnosti, můžeš třeba mít oprávnění k přístupu k souborům, můžeš si počítat statistiky.

Ale opět záleží, k čemu je ten upload určený. Jde-li ti o upload kofiguráků redakčního systému a chceš zaručit, že ty staré se zazálohují, pak je dobré přejmenovat soubor, tak jak to děláš, ale místo ikska, přidat na konec (před příponu) třeba datum v sestupném formátu (-yyyymmdd-hhmmss), aby se při abecedním řazení zobrazovaly ve vhodném pořadí.

Pokud je ten upload určený veřejnosti, musíš si dávat extra pozor, aby nešlo uploadnout php soubory, aby nešlo includnout soubory z adresáře download (třeba změnou parametru v URL). Je toho prostě víc, než se na první pohled zdá. http://php.vrana.cz/ukladani-souboru-od-uzivatele.php
smiesek
Profil
ano, máte pravdu, děkuju, zatím to není pro nic určeno, je to spíše pokus a pochopení principu práce se soubory a adresáři - upload, přejmenování, výmaz a pak do toho zápisy do souborů apod. :-)

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: