[PHP] Wysyłanie pliku na serwer
Aby ułatwić sobie oraz innym webdeveloperom operacje na plikach, a konkretnie zapisywanie pliku w odpowiednim miejscu na serwerze, przygotowałem odpowiednią i bardzo łatwą w obsłudze funkcję. Dzięki prostocie i kilku przydatnym opcjom można ją łatwo zaimplementować w swoim projecie.
Poniżej przedstawiam funkcję i pokrótce omówię jej zastosowanie.
upload.func.php
<?php
/*
* File: upload.func.php
* Title: Funkcja zapisująca plik na serwerze.
* Author: Wojciech Król
* Copyright: 2012 Wojciech Król
* License: GNU GPL version 3
*
* Example:
<?php
require_once("upload.func.php");
if(isset($_POST['submit'])) {
switch(uploadFile('image','example/', 'jpg|gif|png|jpeg', 0)) {
case 0: echo "No file uploaded!"; break;
case 1: echo "Failed to save file!"; break;
case 2: echo "File saved!"; break;
case 3: echo "Invalid file extension!"; break;
case 4: echo "File already exists!";
}
}
?>
<form method="post" action="" enctype="multipart/form-data">
<input type="file" name="image" />
<input type="submit" name="submit" />
</form>
* INFO:
* Ostatni i przedostatni parametr ($file_name oraz $overwrite) jest opcjonalny.
* $overwrite służy do nadpisywanie pliku. 1 - Nadpisuj(domyślnie), 0 - Nie nadpisuj
* $file_name służy do ustawienia stałej nazwy pliku. Pominięcie tego paramteru oznacza nadanie oryginalnej nazwy pliku.
*
*/
function uploadFile($input_name, $dir, $file_type, $overwrite = 1, $file_name = NULL) {
if(!$_FILES[$input_name]['name']) return 0;
$ex = explode("|",$file_type);
$file_ex = explode(".",$_FILES[$input_name]['name']);
$c_file_ex = count($file_ex);
for($i=0; $i<count($ex); $i++) {
if($file_ex[$c_file_ex-1] === $ex[$i]) {
if($file_name == NULL) {
if($overwrite == 0 AND file_exists($dir.$_FILES[$input_name]['name'])) return 4;
if(!move_uploaded_file($_FILES[$input_name]['tmp_name'],$dir.$_FILES[$input_name]['name'])) return 1;
else return 2;
}
else {
if($overwrite == 0 AND file_exists($dir.$file_name.".".$file_ex[$c_file_ex-1])) return 4;
if(!move_uploaded_file($_FILES[$input_name]['tmp_name'],$dir.$file_name.".".$file_ex[$c_file_ex-1])) return 1;
else return 2;
}
}
if($i+1 == count($ex)) return 3;
}
}
?>
Zastosowanie funkcji przedstawię nie inaczej jak na przykładach :-)
Składnia:
switch(uploadFile('nazwa_kontrolki','folder_docelowy/', 'rozszerzenie1|rozszerzenie2|roszerzenie3')) {
case 0: echo "Nie wybrano pliku!"; break; // Komunikat o nie wybraniu pliku
case 1: echo "Nie udało się zapisać pliku!"; break; // Komunikat o niepowodzeniu przy zapisywaniu
case 2: echo "Plik zapisany!"; break; //Komunikat przy pomyślnym zapisie
case 3: echo "Niepoprawne rozszerzenie pliku!"; break; //Komunikat o niepoprawnym roszerzeniu
case 4: echo "Plik już istnieje!"; //Komunikat o już istniejącym pliku o tej samej nazwie i rozszerzeniu
}
Przykład 1: Wysyłanie obrazków przez formularz
require_once("upload.func.php");
if(isset($_POST['submit'])) {
switch(uploadFile('image','example/', 'jpg|jpeg|gif|png')) {
case 0: echo "Nie wybrano pliku!"; break;
case 1: echo "Nie udało się zapisać pliku!"; break;
case 2: echo "Plik zapisany!"; break;
case 3: echo "Niepoprawne rozszerzenie pliku!"; break;
case 4: echo "Plik już istnieje!";
}
}
?>
<form method="post" action="" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" name="submit">
</form>
Przykład 2: Nadpisywanie istniejącego już pliku
(...)
switch(uploadFile('nazwa_kontrolki','example/', 'zip|rar', 1)) {
case 0: echo "Nie wybrano pliku!"; break;
case 1: echo "Nie udało się zapisać pliku!"; break;
case 2: echo "Plik zapisany!"; break;
case 3: echo "Niepoprawne rozszerzenie pliku!"; break;
case 4: echo "Plik już istnieje!";
}
(...)
Czwarty parametr funkcji (0 lub 1) odpowiada za nadpisywanie pliku. Dla 1- istniejący pli zostanie nadpisany, dla 0-plik o identycznej nazwie i rozszerzeniu pozostanie bez zmian i skrypt zwróci błąd o istniejącym już pliku (przypadek 4)
Przykład 3: Plik z nową, stałą nazwą
(...)
switch(uploadFile('nazwa_kontrolki','example/', 'zip|rar', 1, 'nowa_nazwa')) {
case 0: echo "Nie wybrano pliku!"; break;
case 1: echo "Nie udało się zapisać pliku!"; break;
case 2: echo "Plik zapisany!"; break;
case 3: echo "Niepoprawne rozszerzenie pliku!"; break;
case 4: echo "Plik już istnieje!";
}
(...)
Przykład 4: Wyłączenie komunikatów
(...)
uploadFile('nazwa_kontrolki','example/', 'zip|rar', 1, 'nowa_nazwa');
(...)
W tym przykładzie funkcję uploadFile wystarczy wyciągnąć z instrukcji switch. Dzięki temu funkcja nie będzie wyświetlać błędów lub informacji na temat wysłanego/zapisanego pliku.
To na tyle. Wszelkie błędy lub dolegliwości w skrypcie oczywiście piszcie w komentarzach :)
Komentarze
1. Funkcja explode jest strasznie wolna, nie lepiej jako parametr funkcji wysłać tablicę rozszerzeń?
2. Rozszerzenie sprawdzasz po nazwie pliku, czyli bardzo łatwo oszukać Twój skrypt. Zainteresuj się funkcjami do pobierania informacji o plikach, w szczególności o atrybucie \'mime\'
3. Zamiast robić pętle, wystarczyło skorzystać z funkcji in_array ;)
4. Niepotrzebnie dwa razy powtarzasz count dla zmiennej $ex. Dodatkowo, w pętli for ten count wykonywany będzie tyle razy, ile jest elementów w tej tablicy. Spowalnia to strasznie wykonywanie skryptu (wiadomo, ułamki sekund, ale co gdy nagle wykonuje go tysiące użytkowników?) To bardzo częsty błąd początkujących ;)
5. Końcowy warunek jest niepotrzebny. Skoro nic wcześniej nie wywołało returna, to po co sprawdzać, czy należy użyć ostatecznego returna?
6. Nie powinno się odwoływać do zmiennych serwerowych w funkcjach. Zamiast przekazywać nazwę kontrolki, nie lepiej przekazać ją po prostu w argumencie? W przyszłości taki nawyk, może Ci bardzo zaszkodzić, przy większym projekcie, gdy nagle całość zacznie się krzaczyć i ciężko będzie znaleźć błąd.
7. Może to drobiazg, ale używaj && zamiast AND. Po kilku latach studiowania oraz pracy w branży IT, nikt już tego nie używa w ten sposób...
Ogólnie to dużo ćwicz, przeglądaj kody źródłowe dużych CMSów i zainteresuj się jakimś frameworkiem, polecam Symfony, jest bardzo trudny dla początkujących, ale gdy go ogarniesz, bardzo wiele się nauczysz :) Wyćwiczysz też sobie pewne nawyki i konwencje, które warto znać od samego początku.
Życzę powodzenia, też kiedyś zaczynałem (w podobnym wieku jak Ty) i popełniałem te same błędy... ;)
Pozdrawiam,
Damian
if(filesize($_FILES[\'obrazek\'][\'tmp_name\'])) {
$data_img = date(\"YmdHis\");
$nazwa = $_POST[\'nazwa\'];
$sp1 = explode(\".\",($_FILES[\'obrazek\'][\'name\']));
$uploaddir = \'../upload/\'.$data_img.\'.\'.$sp1[1];
switch(uploadFile(\'obrazek\',\'../upload/\', \'jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG\', 0, $data_img)) {
case 0: echo \"Nie wybrano pliku do załadowania!\"; break;
case 1: echo \"Wgrywanie pliku nie powiodło się.\"; break;
case 2:
mysql_query(\"INSERT INTO galeria VALUES(0, \'$uploaddir\', \'asdasdad\', \'$nazwa\')\");
echo \"Plik zapisany!\"; break;
case 3: echo \"Niedozwolone rozszerzenie pliku!\"; break;
case 4: echo \"Taki plik już istnieje.\";
}
}
Jak zrobic aby mozna bylo zuploadowac 2 obrazki na raz?


