R.E. Uploader

Bár az osztályt nem ma írtam, de most érett meg a publikálásra. Segítségével egyszerűbben, felhasználóbarátabban oldható meg fájlok feltöltése és képek esetén thumbnail kép automatikus készítése. A maximális fájlméret és fájltípus korlátozható. A fájlok neve és könyvtára is megadható. Eredeti és kép esetén thumbnail képek könyvtára is. Fájlnév egyezés esetén a fájlok felülírhatók, vagy kaphatnak numerikus megkülönböztető jelet. Pl.: "_1". A fájlok egyelőre minden esetben csak url barát formában menthetők el. Tehát nincs se szóköz, se speciális karakter. Ezek automatikusan lesznek lecserélve ékezetmentes karakterekre. Vagy speciális karakterek esetén a rájuk leginkább hasonlító egyszerű karakterre.

Legújabb verzió letöltése sourceforge-ról

Példa: (csak a "file[egyik]" nevű inputtal foglalkozik.)

<?php
require_once 'Uploader.php';
$msg = "";
$up = new Uploader();
$up->setInputName('file[egyik]');
if ($up->requested()) {
        if ($up->validate(array(Uploader::E_NO_FILE))) {
                $up->upload();
                $msg = "Sikeres fájlfeltöltés";
        } else {
                $msg = implode("<br />\n", $up->errorMessages());
        }
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <title></title>
                <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        </head>
        <body>
                <div id="container">
                        <div id="msg"><?php print $msg; ?></div>
                        <form action="" method="post" enctype="multipart/form-data">
                                <div>
                                        <input type="hidden" name="MAX_FILE_SIZE" value="50000" />
                                        Fájl: <input type="file" name="file[egyik][]" />
                                        <br /><input type="file" name="file[masik][]" />
                                        <input type="submit" value="Feltöltés" />
                                </div>
                        </form>
                </div>
        </body>
</html>

Metódusok:

defaultReplacement($defaultReplacement=null):
Visszaadja, hogy a fájlok automatikus átnevezésekor mire legyenek helyettesítve az ismeretlen, vagy a whitespace karakterek. Alapértelmezett: '-'
$defaultReplacement paramétert megadva be is állítja az értéket.

thumbnail($onoff=null):
Visszaadja, hogy kell-e thumbnmail kép is (logikai érték).
Az logikai $onoff paraméterrel hívva be- vagy kikapcsolja azt előtte. Metódus aliasok a be és kikapcsolásra:
thumbnailOn() és thumbnailOff()
(Nyilván ezeknek csak képfeltöltésnél van értelme)

overwrite($onoff=null):
Visszaadja logikai értékként, hogy a már létező, azonos nevű fájlokat felül kell-e írni.
Az logikai $onoff paraméterrel hívva be- vagy kikapcsolja a felülírást előtte. Metódus aliasok a be és kikapcsolásra:
overwriteOn() és overwriteOff()

ignoreExtension($onoff=null):
Visszaadja, legyen-e figyelmen kívül hagyva a kiterjesztés fájlnév egyezés vizsgálatkor true, ha igen. Egyébként false. Vagyis ha a fájlnév csak a kiterjesztésben különbözik, akkor is felülírja, ha az overwrite(true) vagy overwriteOn() meg lett hívva. Akkor hasznos, ha például egy avatart kell feltölteni, de annak lehet png vagy jpg is a kiterjesztése, vagy akár gif. Így csak maradhat! Mármint avatar...
Az $onoff paraméterrel hívva az érték beállítható.
Metódus aliasok az érték állítására: ignoreExtensionOn() és ignoreExtensionOff()

setThumbnailFolder($thumbnailFolder):
Beállítja a thumbnail képek könyvtárát.

setThumbnailName($pattern):
Beállítja a thumbnail kép nevét. Több fájl esetén hasznos a {name} string használata, ami a hozzá tartozó eredeti nagy kép nevét tartalmazza kiterjesztés nélkül. Így elé ( vagy mögé ) írható előtag is, hogy ne írja felül az eredeti képet, ha nem külön mappába töltjük a kis képeket. például: thumb_{name}. Ami egyébként az alapértelmezett érték is.

setThumbnailSize($width, $height):
A thumbnail képek maximális szélességét és magasságát állítja be.

setInputName($name):
A fájl input neve, aminek a fájljait fel szeretnénk tölteni. Például:

$up->setInputName("file[avatar]");

Érvényes a "file[avatar]" és a "file[avatar][]" nevekre is. Automatikusan érzékeli, hogy tömbként lett-e megadva az inputnév.

setMaxFileSize($size, $sizetype = Uploader::SIZE_BYTE):
Beállítja a maximális fájlméretet, ami feltölthető. Alapértelmezetten byte-ban kell a méretet megadni. A második paramétert megadva viszont ( Uploader::SIZE_BYTE vagy Uploader::SIZE_KILOBYTE vagy Uploader::SIZE_MEGABYTE ) megadható, hogy a $size paramétert kilobájtnak, vagy megabájtnak tekintse

getMaxFileSize($sizetype = Uploader::SIZE_BYTE):
Visszaadja a maximális fájlméretet. Alapértelmezetten bájtban, de a $sizetype paraméterrel ( Uploader::SIZE_BYTE vagy Uploader::SIZE_KILOBYTE vagy Uploader::SIZE_MEGABYTE ) módosítható kilobájtra vagy megabájtra.

addType($type,$subType=null,$extension=null):
Korlátozható a feltölthető fájlok mime típusa. A mime típusok főtípus/altípus alakúak. Például image/jpeg. A $type paraméterben a főtípust elég megadni. Ha az altípust is korlátozni szeretnénk, akkor azt a $subType paraméterben kell megadni. Ha az altípushoz konkrét kiterjesztést is rendelünk, mint például jpeg típus csak "jpg" lehet, de "jpeg" nem, akkor azt az $extension paraméterben kell megadni.

typeExists($type):
Létezik-e a $type főtípus a típuskorlátozások között.

subTypeExists($type, $subType):
Létezik-e a $type főtípushoz tartozó $subType altípus a típuskorlátozások között.

isAllowedType($mimetype):
Engedélyezett-e a megadott mimetype típus.

errorMessages():
Visszaadja a hibaüzenetek tömbjét.

validate($ignore=array()):
Visszaadja, hogy érvényes-e minden feltöltendő fájl. Az $ignore tömbben felsorolható, hogy milyen hibaüzeneteket hagyjon figyelmen kívül. Ezek a következők lehetnek:

  • Uploader::E_INI_SIZE: A fájl mérete meghaladja a php.ini -ben megengedettet.
  • Uploader::E_FORM_SIZE: A fájl mérete meghaladja az űrlap MAX_FILE_SIZE nevű inputjában megadottat.
  • Uploader::E_PARTIAL: A fájl csak részben lett feltöltve.
  • Uploader::E_NO_FILE: Nem lett fájl kiválasztva.
  • Uploader::E_NO_TMP_DIR: Nem létezik a feltöltéshez szükséges ideiglenes mappa.
  • Uploader::E_MAX_SIZE: A fájl mérete meghaladja a setMaxFileSize() metódussal megadottat.
  • Uploader::E_TYPE: A fájl nem megengedett típusú
  • Uploader::E_ERROR: Ismeretlen hiba
  • Uploader::E_CANT_WRITE_FOLDER: A cél mappa nem írható.
  • Uploader::E_CANT_WRITE_DISK: A lemez nem írható.

getValueByIndex($index):
A $_FILES tömbnek a name, tmp_name, size, type vagy error indexeiben található értékeket adja vissza tömbként. Azért van rá szükség, mert attól függően, hogy a file input neve tömbként van-e megadva, másképp érhetők el ezek az értékek. Ezzel az elérés módja fix.

requested():
Visszaadja, hány fájl input lett elküldve a setInputName() metódusban megadott névhez tartozóan. Ezzel egyszerűen ellenőrizhető, hogy egyáltalán el lett-e küldve feltöltendő fájl. Hisz ha az inputok száma nem nulla, akkor volt kérelem.

setFolder($folder):
A feltöltendő fájl(ok) könyvtárának beállítása.

upload($filenames=null):
A fájlok feltöltése. A $filenames paraméterben megadható a feltöltendő fájlok új nevei tömbben. Olyan sorrendben, ahogy az űrlapon következnek egymás után. Vagy az indexet is meg kell adni kézzel. Mert az alapján nevezi át a fájlokat. Vagy string, ha a felöltő input is csak egy értéket tartalmaz. Tehát nem [] a vége.
Egyúttal visszaad egy tömböt, aminek egyelőre egyetlen indexe a "filename". A fájlok új neveit tartalmazza egy tömbben. Akkor érdekes, ha volt már azonos nevű fájl, de a felülírás nem volt engedélyezve. Ilyenkor egy numerikus megkülönböztető jelet kapnak a fájl végén. Ha feltöltés után azonnal linkelni is kell a fájlokat, akkor jó tudni a nevüket is.

Kategóriák: 
Megosztás/Mentés

Hozzászólások

Tonek képe

Szia.
Két kérdésem lenne!.Az eggyik az,hogy hogyan lehet a feltöltendő fájloknak új mappát létrehozni?
mert ugye most a gyökérbe menti el a fájlokat.
A másik kérdés az lenne hogy lehet a feltöltött fájlokat vissza linkelni.
pl:admin felületen feltöltök egy fájlt akkor az jelenjen meg a weboldalon letöltő link formájában.
Válaszodat előre is köszönöm.

Rimelek képe

Szia. Lehet nem értem a kérdésed, de a feltöltő létrehozza magának a mappát, amit megadsz a setFolder -ben és setThumbnailFolder -ben. Nem csak a gyökérbe lehet természetesen feltölteni. Ha van egy images mappád, amiben több kategória szerint vannak képek és ide akarod tölteni a feltöltendőt is, akkor egy belső mappát állítsd be a feltöltőnek. Ha a nagy és kis képet akarod egy közös mappába feltölteni, akkor szintén a mappákat kell úgy beállítanod. Valamint a thumnail kép nevét, hogy ne írja felül az eredeti képet.

Az upload metódus visszaadja egy tömbben a feltöltött fájlok infóit ( jelenleg csak a neveit ). Abból össze tudod rakni a linkeket.

slowr képe

Szia!
Az előző írásom hibás, pedig visszaolvastam...
;-)

Az
upload függvény
746-ik, 748-ik sorában használt
$value nevezetű változó előtte sehol nem szerepel, nincs deklarálva.
Ez hiba vagy csak én nem vettem észre valamit?

Rimelek képe

Szia

A hibás kérdésed töröltem is.

Amit leírtál, tényleg hibának tűnik. Megnéztem a forrást most. Én sem látom, hogy valahol létrehoztam volna a változót. Az a $value valószínűleg $n akart lenni.

Köszönöm, hogy jelezted! Javítani fogom majd.

Rimelek képe

Javítottam a hibát és feltöltöttem 1.0.1 -es verziószámmal az újat. Tényleg köszönöm, hogy jelezted a hibát!

Fancsik Tamás képe

Nem sikerült beállítanom, hogy képfeltöltés esetén miniatűr is készüljön.
Továbbá szeretnék abban is segítséget kérni, hogy hogy lehet a feltöltött képet automatikusan átméretezni, tömöríteni.

Rimelek képe

Leírnád, hogy hogyan próbálkoztál?

A miniatűr képek készítését a thumbnailOn() metódussal tudod bekapcsolni. És emellett állíthatod, hogy mekkorára méretezze. De tömörítés nincsen. Illetve az eredeti fájl sem méreteződik át sajnos. Csak akkor, ha a thumbnail kép készítését úgy állítod be, hogy felülírja az eredetit. De akkor csak az az 1 kép marad meg. Ez már eszembe jutott korábban is, hogy kéne rajta változtatni, de eddig nem tettem. Szóval az eredeti méretű feltöltött képet külön kell átméretezned.

Fancsik Tamás képe

így próbáltam:

$up->setthumbnailOn = true;
$up->setthumbnailFolder('files');

Rimelek képe

Nincs olyan, hogy setThumbnailOn, pláne nem tulajdonságként. Metódusok vannak. A fent írtakból válogathatsz a bejegyzésből. thumbnailOn() metódus van, ahogy azt az előző válaszomban is írtam.

$up->thumbnailOn();

Fancsik Tamás képe

Jól értelmezem?

<?php
require_once 'uploader.php';
$msg = "";
$up = new Uploader();
$up->setInputName('file[egyik]');
$up->setFolder('pictures');
$up->setthumbnailFolder('pict_thumbnail');
$up->thumbnailOn();
if ($up->requested()) {
        if ($up->validate(array(Uploader::E_NO_FILE))) {
                $up->upload();
                $msg = "Sikeres fájlfeltöltés";
        } else {
                $msg = implode("<br />\n", $up->errorMessages());
        }
}
?>
Rimelek képe

Jajj, ne haragudj! Csak most látom, hogy erre nem reagáltam. Igen, Így kellene működnie.

Kiss János képe

Hogyan lehetne több inputot felvinni egy submitra, szóval több képet felvinni egyszerre, vagyis felviszi a képeket ha két input mezőt rakok a lapba, de az uploader.php ban ahol sessionba teszem a kép nevét
$_SESSION['kepneve']= $filename;
csak az egyik kép neve lesz benne, és nekem ebből kellene az adatbázis egy sorába beírni a képek neveit.
köszönöm

Rimelek képe

Egy inputtal egy fájlt lehet feltölteni. De ha több inputot használsz, azt felismeri a feltöltő. A setInputName metódusnál van a magyarázat.

Az upload metódus pedig visszaadja a feltöltött fájlok neveit. Azt felhasználhatod bármire.

Kiss János képe

köszönöm, de hogy tegyem be például 3 inputban feltöltött kép nevét egy sessionba?( A képeket feltölti a mappába)
Ha egy képet töltök fel úgy ahogy fent írtam $filename-t szépen beteszi sessionba, amit be tudok már insertelni a táblába a feltöltött termék többi adata mellé, csak én egy termékhez több képet szeretnék.

Rimelek képe

Nem tudom, honnan van a $filename változód, de amit én javasoltam, ott több fájlneved kell legyen. És azt is beteheted session-be, ha kell.

$ret = $uploader->upload();
$_SESSION['kepekneve'] = $ret['filename'];

Így nem értem a problémát. Ha még most sem világos a megoldás, akkor próbáld másképp kérdezni. Egyszer majd csak megértem.

Anonymous képe

Szia! Lenne pár kérdésem.

- Pontosan, hogy lehet megadni és hol, hogy csak pl.: jpg, gif, jpeg képeket lehessen feltölteni?
- Ha pl. simán a feltöltésre megyek azt írja sikeres. Miért nem azt adja hogy nincs fájl vagy hiba?
- Hogy írathatom adatbázisba a képek nevét, elérési linkjét, feltöltés dátumát, és a feltöltő (bejelentkezés után elért az egész feltöltő rész) ID-jét.
- Eztán hogyan lehet kilistázni a képek neveit úgy hogy mellette legyen egy törlés link, amivel törölni is tudja a felhasználó.

Nagyon fontos lenne, köszönöm előre is!

Rimelek képe

1. mime típusokra lehet korlátozni elsősorban. És azon belül kiterjesztésre.

$up->addType('image', 'jpeg', 'jpg'); //image/jpeg mime típusra és jpg kiteresztésre is korlátoz
$up->addType('image', 'gif'); //csak image/gif mime típusra korlátoz.

2. hogy mit ír ki, az tőled függ. Hibatípusok vannak. Én a példában beírtam a validate metódushívásba az E_NO_FILE hibát, mint kivételt. Ezért nem veszi hibának, ha nincs megadva fájl.

3. Az upload metódus leírásánál említettem, hogy visszaadja a filename indexben a feltöltött fájlok neveit. Azt, hogy melyik mappába töltötte fel, pedig hozzá lehet csapni, mert az fixen állítható. A feltöltés dátuma, a feltöltő id-je pedig teljesen független a feltöltő programtól. Amikor az upload metódust meghívod és a fájlok feltöltődnek, akkor futtatsz egy adatbázisba írást a megfelelő paraméterekkel. Hogy az nálad honnan jön, azt már te tudod.

4. A listázás is a te megoldásodtól függ. Adatbázisból is lekérheted a feltöltött fájlokat a nevükkel vagy fájlrendszerről is listázhatod őket. Gondolom, adatbázisból fogod. Mellé pedig kirakhatsz bármilyen linket. Ha átadod url-ben a kép adatbázisban tárolt id-jét vagy a kép nevét is a fájltörlő szkriptnek, akkor abból tudod, melyik fájlt kell kitörölni. Törlöd adatbázisból és a fájlrendszerről is.

Ha valami nem érthető, akkor arra a részre konkrétabban kérdezz rá, mert van egy olyan érzésem, hogy ennél pontosabb választ vártál, de a kérdéseid nagy részére ott a válasz a bejegyzésben vagy pedig alap php ismeretet igényel. Így nem tudom, mit írhatnék még. Hogy mennyire értesz hozzá.

Nem ígérek gyors választ, mivel holnap csak este leszek otthon.

Anonymous képe

Köszönöm a gyors választ. Még biztos lesz kérdésem. Estig hátha jön majd kérdés, addig pedig ezt értelmezem és javítgatom. Köszönöm még egyszer!

Anonymous képe

Szia!

A leírásban olvasott "egyúttal visszaad egy tömböt, aminek egyelőre egyetlen indexe a "filename"."

ebből a

 $uploaded[] = array(
'filename' => $filename

szeretném megkapni az input mezőkből feltöltött képek neveit.
Leíráshoz tartozó több kép egy formban történő feltöltést szeretnék, ami után az adatbázisban lennének a hozzájuk tartozó képek nevei a termékek mellett.

Köszönöm

Rimelek képe

Szia. És hol akadtál el vele? Az upload metódus tényleg visszaadja a fájlok neveit egy tömbben, ahogy írtam. Ez innentől már egy elemi feladat ciklusban feldolgozni a visszatérési értéket. Az első nevet például így érnéd el ciklus nélkül, ha az $uploaded változóba teszed az upload metódus visszatérési értékét:

echo $uploaded[0]['filename'];
Anonymous képe

Sajnálom nekem nem megy ciklusba írva kiíratni az alábbiból az egy formból egy submit nyomásra feltöltött képek neveit akárhogy próbálkozom

$uploaded[] = array(
        'filename' => $filename
);

ebben kérném a segítséged.
Abban sem vagyok biztos, hogy az a megfelelő html forma a több kép feltöltésre amit a leírásban találtam.

<input type="hidden" name="MAX_FILE_SIZE" value="" />
Kép feltöltés: <input type="file" value=""name="file[egyik][]" />  
                                       
<br>
<br>
<input type="hidden" name="MAX_FILE_SIZE" value="" />
Kép feltöltés: <input type="file" value=""name="file[masik][]" />  
Rimelek képe

Nem értem, miért idézed mindig azt a php kódot, ami az upload metódusban van és amivel neked semmi dolgod, és nekem sem segít megérteni a problémád.

A html-ed a példakódom másolata, aminek az elején leírtam, hogy az csak a file[egyik] inputtal foglalkozik. És azt is leírtam, hogy mivel lehet a nevet beállítani. A setInputName() metódussal. De ha nincs speciális igényed, csak két fájlt akarsz egyszerre feltölteni, akkor a html-ben mindegyik input neve file[] legyen és ne is változtass a setinputName-mel az input nevén php-ból sem.

<input name="file[]" type="file" />

A ciklusban kiírásnál mi a probléma? Ha jobban részletezed, miket próbáltál és melyik résznél milyen rendellenességet tapasztaltál, abban tudok segíteni. Bár ez tényleg elemi, de ha a ciklus megírásában is elakadtál, akkor alább a megoldás (de akkor jobban utána kell járnod a php-nek)

$files = $up->upload();
foreach ($files as $file) {
   echo $file['filename'].'<br />';
}
Anonymous képe

Lehet, jobban utána kell járnom, de most ha ezt teszem bele, hogy majd ebből a tömbből kivegyem a neveket sem megy

$_SESSION['kepneve']=array();

$_SESSION['kepneve'][] = $filename;

Annyit szeretnék, hogy a két input mezőből kinyerjem a képek neveit amit az adatbázisban a termék egyéb dolgaihoz egy sorban inserttel be tudnék tenni.

Rimelek képe

Ha csak bemásolsz nekem kódrészleteket, de nem írod, hova írtad azt, akkor nem tudok segíteni. Viszont az upload metódus belsejébe remélem nem módosítasz semmit. Még a ciklust is megírtam neked. Innentől, ha azt kipróbáltad és nem ment, akkor az űrlapod rossz. Másold be nekem az egész forráskódodat, ami a feltöltéssel kapcsolatos és megnézem. Ha van benne titkos adat, amit nem tennél ki a netre, akkor írd emailben a fenti "Kapcsolat" menüponton keresztül.

Anonymous képe

Szia!
Segítségedet szeretném kérni abban, hogy hogyan lehet beállítani a feltöltendő fájl méretét.
Fel szeretnék tölteni max 3 megás fájlt.
Az objektum példány setmaxfilesize metódusát így kell beállíani?
$size=3;
up->setMaxFileSize($size, $sizetype = Uploader::SIZE_MEGABYTE):

köszönettel,
Gábor

Rimelek képe

Szia. Így is működne, de a bejegyzésben a metódus definíció van. Neked nem kell a $sizetype-nak helyben értéket adni és a $size értékét is beírhatod közvetlenül.

$up->setMaxFileSize(3, Uploader::SIZE_MEGABYTE);

Persze kiteheted őket változóba, de akkor így néz ki:

$size = 3;
$sizetype = Uploader::SIZE_MEGABYTE;
$up->setMaxFileSize($size, $sizetype);
Anonymous képe

Köszi a gyors választ:-) !!!
üdvözlettel,
Gábor