Fájl feltöltés ellenőrzése, és feltöltött fájl nevének megváltoztatása.
Sziasztok
Van egy fájlfeltöltő formom, feltöltéskor ellenőrzi hogy nem üresek-e a mezők, és ellenőrzi a feltöltött fájl tulajdonságait (méret, formátum). A problémám az hogy úgy szeretném megoldani hogy ne legyen kötelező fájlt feltölteni, de ha mégis tölt fel akkor legyen leellenőrizve a feltöltött fájl. Ha nem tölt fel, tehát a fájlfeltöltő mező üresen marad akkor hagyja figyelmen kívűl.
A másik problémám hogy szeretném megváltoztatni a feltöltött fájl nevét, így szeretném elkerülni hogy ha 2 felhasználó ugyanazzal a névvel tölt fel képet, akkor a lekérésnél ne legyen kavarás. Ezt előszőr úgy próbáltam hogy az aktuális időpontot ($time()) hozzáadtam a feltöltésnél, sikerült is megváltoztatni a fájl nevét, viszont a mysql-be az eredeti nevet írta be, így nem tudta megjeleníteni a képet. Nem egyezett a két név, összegezve nem tudtam megoldani hogy a mysql-be ugyanaz a név kerüljön mint ami a neve a mappában.
Ha nem nagy kérés akkor a segítség mellé egy kis magyarázatot is adjatok, mert érteni szeretném nem kimásolni.
Előre is köszi segítséget / kritikát
A kód:
■ Van egy fájlfeltöltő formom, feltöltéskor ellenőrzi hogy nem üresek-e a mezők, és ellenőrzi a feltöltött fájl tulajdonságait (méret, formátum). A problémám az hogy úgy szeretném megoldani hogy ne legyen kötelező fájlt feltölteni, de ha mégis tölt fel akkor legyen leellenőrizve a feltöltött fájl. Ha nem tölt fel, tehát a fájlfeltöltő mező üresen marad akkor hagyja figyelmen kívűl.
A másik problémám hogy szeretném megváltoztatni a feltöltött fájl nevét, így szeretném elkerülni hogy ha 2 felhasználó ugyanazzal a névvel tölt fel képet, akkor a lekérésnél ne legyen kavarás. Ezt előszőr úgy próbáltam hogy az aktuális időpontot ($time()) hozzáadtam a feltöltésnél, sikerült is megváltoztatni a fájl nevét, viszont a mysql-be az eredeti nevet írta be, így nem tudta megjeleníteni a képet. Nem egyezett a két név, összegezve nem tudtam megoldani hogy a mysql-be ugyanaz a név kerüljön mint ami a neve a mappában.
Ha nem nagy kérés akkor a segítség mellé egy kis magyarázatot is adjatok, mert érteni szeretném nem kimásolni.
Előre is köszi segítséget / kritikát
A kód:
require_once('adatok.php');
require_once('kapcsadatok.php');
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$name = mysqli_real_escape_string($dbc, trim($_POST['name']));
$username = mysqli_real_escape_string($dbc, trim($_POST['username']));
$screenshot1 = mysqli_real_escape_string($dbc, trim($_FILES['screenshot1']['name']));
$screenshot1_type = $_FILES['screenshot1']['type'];
$screenshot1_size = $_FILES['screenshot1']['size'];
$screenshot2 = mysqli_real_escape_string($dbc, trim($_FILES['screenshot2']['name']));
$screenshot2_type = $_FILES['screenshot2']['type'];
$screenshot2_size = $_FILES['screenshot2']['size'];
if (!empty($name) && !empty($username) && (!empty($screenshot1))&& (!empty($screenshot2)))
{
if ((($screenshot1_type == 'image/jpeg') || ($screenshot1_type == 'image/pjpeg'))
&& ($screenshot1_size > 0) && ($screenshot1_size <= TT_MAXFILESIZE)) {
if ($_FILES['screenshot1']['error'] == 0) {
$target = TT_UPLOADPATH . $screenshot1;
if (move_uploaded_file($_FILES['screenshot1']['tmp_name'], $target))
{
if ((($screenshot2_type == 'image/jpeg') || ($screenshot2_type == 'image/pjpeg'))
&& ($screenshot2_size > 0) && ($screenshot2_size <= TT_MAXFILESIZE)) {
if ($_FILES['screenshot2']['error'] == 0) {
$target = TT_UPLOADPATH . $screenshot2;
if (move_uploaded_file($_FILES['screenshot2']['tmp_name'], $target))
$query = "INSERT INTO users (name, username, screenshot1, screenshot2) VALUES ('$name', '$username', '$time()$screenshot1', '$screenshot2')";
mysqli_query($dbc, $query);
echo '<p>Az általad feltöltött adatok:</p>';
echo '<p>'. $name .'</p>';
echo '<p>'. $username .'</p>';
echo '<img src="' . TT_UPLOADPATH . $screenshot1 . '"/>';
echo '<img src="' . TT_UPLOADPATH . $screenshot2 . '"/>';
$name = "";
$username = "";
$screenshot1 = "";
$screenshot2 = "";
mysqli_close($dbc);
}
}
}
}
}
}
<form method="post" enctype="multipart/form-data" value="<?php echo $_SERVER['PHP_SELF']; ?>"/>
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo TT_MAXFILESIZE; ?>" />
<label for="name">Név:</label>
<input type="text" id="name" name="name" value="<?php if (!empty($name)) echo $name; ?>"/>
<label for="username">Felhasználónév:</label>
<input type="text" id="username" name="username" value="<?php if (!empty($username)) echo $username; ?>"/>
<label for="screenshot1">1. Kép</label>
<input type="file" id="screenshot1" name="screenshot1">
<label for="screenshot2">2. Kép</label>
<input type="file" id="screenshot2" name="screenshot2">
<input type="submit" name="submit" value="submit">
</form>
A form kiamardt
Kódszínezés és szerkesztés
Lassan a testtel
Ki lehetne emelni jobban a
Esetleg automatikusan
Hát ha írsz egy regex-et, ami
Nyilván nincs tökéletes
if.?\(.*?\)
, az pl jó eséllyel valamilyen kód... Nyilván lehetnek fals pozitív visszajelzések, ahogy a Gmail is mindig szól, ha a levelemben leírom a "csatolmány" szót, és nem csatolok semmit a levélhez.$_FILES tömb
$_FILES
tömb üres, akkor tudhatod, hogy nem töltött fel fájlt, így e szerint járhatsz el.A
move_uploaded_file()
függvénynek a cél paraméterében adhatod meg az új fájlnevet, így az adatbázisba való feltöltés során is ezt kell használnod. Célszerű véletlenül generálni fájlnevet (pl. egy 10 karakteres számsor). Így elkerülhető, hogy a fájlnévben esetlegesen szereplő különleges (nem ASCII) karakterek zavart okozzanak a fájl elérésében, és egyébként is hasznos, ha a felhasználó saját fájlnevét nem használja az oldal.A legenerálás után az
is_file()
függvénnyel megnézed, hogy létezik-e fájl a célmappában azzal a névvel (10 karakteres számnál ez elég ritkán fordul elő, de ha kihagyod, sok fájl esetén egyezőségnél kérdés nélkül felülírná az eredetit), és ha létezik, új nevet generálsz, amíg nem találsz olyat, amilyen nevű fájl még nem létezik.Erre hasznos a viszonylag ritkán használt do-while ciklus, pszeudo-kóddal:
U.i.: A későbbiekben, kérlek, használd a kódszínezőt - jelen esetben nem égető probléma, mert a válaszhoz nem volt szükséges az idézett kód, de a következőkben hasznos, amennyiben érdemi válaszokat szeretnél kapni kevésbé általános kérdésekre.
Ha jól emlékszem sima
A név ütközés úgy is elkerülhető, ha eléfűzöd a timestampet...
szerk:
Közben kiderült, hogy a move_uploaded_files a register globals ellen véd, meg hogyha letiltják a wwwroot-on kívüli fájl műveleteket, akkor is bele tud nyúlni az upload dir-be.
Egységes fájlnevek
A timestamp pedig "csak" másodperc-pontos, ami nagy forgalom esetén már okozhat problémát, ha mindenki "profil.jpg" néven akarná feltölteni a fényképét.
Közösségi oldalnál így nem lehet benne káromkodás, vállalati oldalnál pedig az "Éves jelentés - hatvanharmadik verzió, módosította Icuka (kenőpénzek nélkül!!!).xls" ellen véd :)
Nem úgy értettem, hogy az
fájlok
A kód szinezése miatt bocsi mindenkitől, legközelebb ígérem használom.
Ui: amit beírtam formot csak a példa kedvéért raktam össze, az eredeti form fog bekérni olyan adatokat amik egyedik lesznek, szerintem működne ha azt az adatot rendelném hozzá a kép generált nevéhez. Majd kiderül hétvégén :)
Éljen május 1! Jó pihit mindenkinek!
A fájlnevekbe sose tegyél
Még egy tipp:
Nem hülyeség felhasználónként
Fél megoldás
Tehát egy szöveges rész, meg egy fájlfeltöltő mező. Az előző példában a username bekérése csak a példát szolgálta.
A név módosításra sikerült összebarkácsolnom egy megoldást, működik és elég biztosnak tűnik hogy nem lesz 2 ugyanolyan nevü kép. Hozzárendeltem az aktuális időt is, de egy véltelneszerű számsort is.
Íme:
Azzal most fogok foglalkozni, a hiba bennem van :) ha a kacsa nem tud úszni nem a víz a hülye :)
Ja, használtam a kódszinezőt:)
Ja, használtam a
Ja észrevettem, csodálkoztam is, hogy fejlődőképes vagy! :D
Ezt lenne érdemes használnod SQL-es műveletekre.
http://php.net/manual/en/pdo.prepared-statements.php
Mysqli modulban is vannak hasonló statement sablonok.
http://php.net/manual/en/mysqli.prepare.php
Azért érdemes ezeket használni, mert nem kell kiírni, hogy
mysqli_real_escape_string(blah)
minden egyes változóra, amit escapelni akarsz, és így véletlenül sem felejted el... Amysqli_real_escape_string(blah)
ismételgetése kód duplázás, vagy redundanciának is hívják. Azért rossz, mert az ismétlődő kódot könnyű elgépelni, illetve nehéz karbantartani, átnevezni, átírni, hogy másik interface-el működjön. Mondjuk a legtöbb IDE-ben már van refactoring tool ilyesmiknek a segítésére. Gondolom IDE-t még mindig nem használsz, vagy csak nem találtad meg a reformat code parancsot bennük... Sokat javítana a kódod minőségén, ha automatikus lenne a behúzás.Haladás
move_uploaded_file
.$_FILES
tömb meglétét! Ha létezik, akkor volt fájlfeltöltés (kísérlet). Azután a sikeresség:Nézd át a PHP fájlkezelő függvényeit, valamint a képkezelőket is! (Ebben a válaszban egy csomó kulcsszó van.)
Mime típust is célszerű ellenőrizni, ill. ha csak jpeg kép lehet, akkor megfelelő erőforrásba próbáld betölteni, a méretezéshez úgyis kell. Ha nem sikerül betölteni: nem jpeg kép.
képellenőrzés
A hétvégét rászánom hogy a formomat átalakítsam. Ha sikerül bemásolom :)
A kindulási pont ha a feltöltő mező üres akkor ugorja át, ha nem üres akkor ellenőrizze le a típust, méretet stb.
Oktató?!
Egy kicsit is igényes megrendelővel ezt nem tudod megetetni és nem is szabad ilyet csinálni.
Ne csak a formot alakítsd át, hanem a feldolgozót is! Nem muszáj egy fájlban sem lennie a kettőnek, de eleinte csinálhatod úgy, ahogy neked könnyebb. Figyelj arra is, hogy ami a Júzertől jön bármilyen adat, azt megfelelően escape-eld, mielőtt adatbázisba mented!
Sikeres hétvégét!
Ne ijedj meg a kihívásoktól!
Siker de messze még a hegycsúcs :)
Találtam a neten nagyon jó leírásokat függvényekhez, képfeltöltő formokhoz stb, köszönöm a függvény ajánlást pepitának, inf3rno nak a biztonságra vonatkozó dolgokat, + pkedamnak a név változtatásra vonatkozó segítséget. No meg midnenki másnak aki vette a fáradtságot és segített! (nem gondoltatok még felhasználó név változtatására? ?? :D:D csak egy ötlet)
Tudom hogy "csúnya" meg lehetne tömörebb, összevontabb de most gyakorlom aztán igyekszem minél kevesebb sorban megadni a kódokat.
UI.2: az említett tanárt kérdezték hogy szerinte mi a legjobb védelem egy weboldalnak... azt mondta ha kiírjuk a főoldalra hogy légyszi ne törd fel az oldalt!
Jófej amúgy csak oktatni nem tud :D
De mégegyszer köszi az eddigieket!
Na, egész jó!
Azt kiszúrtam, hogy az elején nem ellenőrzöd (isset) a
$_FILES
tömb meglétét. Így, ha a Júzer tréfás kedvében kézzel begépeli az URL-t, "szép" dolgok történhetnek. Ha valóban saját magára mutat a form (egy fálj az egész), akkor érkezéskor kéne jönnie hibaüzinek rá, ha nincs kikapcsolva.Próbáltad minden lehetőséggel? (Pl. a name nincs megadva)
Szerintem neked öröm segíteni :)
Legalább egy mysql escape
Észrevételek
Ezt kifejtenéd légyszi..?
A formot eléggé hiányosan másoltam be, pl hogy a formot csak akkor kell megjelítenie ha még nem nyomták le a submit gombot, vagy ha valamelyik adat hibás
A felhasználónév változtatást én a weblaboron lévő nicknevekre értettem, kicsit bonyolúltak:D
A biztonságra visszatérve most ismerkedek a regex coach nevü progival, milyen karakter mehet e-mail megadásakor stb.
Bár lehet tényleg keresek egy jó scriptet ami vastag piros betűkkel villogtatja a
:)
Off téma, de ti akik gondolom napi 32 órát dolgoztok gépen hogy csináljátok hogy ne menjen szét a hátatok, gerincetek stb?? én pár hónapja vagyok aktív de mindenem fáj az üléstől ......
Off téma, de ti akik gondolom
Általában azért szokott görnyedni az ember, mert túl alacsonyan van a monitorja... Csinálj egy kezes kitöréseket 5 kilós súlyzóval, attól érezni fogod, ha nem húzod ki magad...
Nem érdemes 24 colnál nagyobb monitort venni, ha közel van, mert szétviszi a szemet. Nekem már késő... :S
Kifejtve
if (isset($_FILES)){...
, így megtudod, hogy volt-e egyáltalán fájlfeltöltés. (Itt lehet, hogy a tömb mindig létezik, akkor még indexbe be kell tenni a form input nevét!)Utána a 18-as válaszomban írt hibaellenőrzés. Ezek megengedő ellenőrzések, csak akkor fut a belső kód, ha minden OK. Helyes sorrendben kell ezeket használni. Belülre mehetnek a te mime és többi ellenőrzéseid.
Postnál érdemes az űrlapod összes elemét nézni, és azt is, hogy nincs-e a vártnál több eleme a
$_POST
tömbnek. Megj., hogy a biztonság az első utána jöhetnek a honlapok, aztán talán a milliók (ez utóbbiakat én még nem találom :().Javaslom, hogy előbb a szimpla fájlkezeléssel foglalkozz, adatbázis és képkezelés nélkül. Ezt csináld meg biztonságosan (esetleg függvényekkel netán osztállyal), csak utána a képkezelést, végül az adatbázist. Jobb is, ha ezeket mindjárt különválasztod, akkor jobban fogod tudni újrahasznosítani - és ez kell a milliókhoz is.
Off: szeretnék én napi 32 órát dolgozni! Jó szék, jó helyzet és időnként mozgás.
köszönöm
Bocsi hogy mostanában nem írtam de sok volt a tanulni való meg a munka, de majd nyáron lesz rá időm és jöhetnek a milliók :)
UI: az isset függvény mibenlétét már értem, a $Files mezőt ellenőrzi, létezik e a feltöltött fájl, ha igen akkor elbohóckodik az ellenőrzésekkel, ha nincs akkor nem fut le az ellenőrzés.
Minden jót nektek! Mégegyszer köszi!
csácsá
Email regex validáció
Itt írtam is róla: StackOverflow - How to validate an Email in PHP?, ha megy az angol, ha nem, akkor szívesen segítek még.
regex
Amennyit kell annyit értek angolúl, de ha valami nem tiszta úgyis zaklatlak majd titeket:)
Köszi az infót bamegakapa :)