[PHP][MySQL][AJAX] Galeria zdjęć ze zmieniającymi się zdjęciami + upload zdjęć na serwer
Korzystając z chwili przerwy w czasie nauki do sesji egzaminacyjnej postanowiłem dzisiaj zaprezentować Ci ciekawy pomysł na galerię zdjęć lub swoisty pokaz slajdów, zależnie od tego jak to potraktujesz.
Ten projekt galerii wykorzystuje zapytania wywoływane przez AJAX do bazy danych MySQL w celu pobrania losowych obrazków do widoku galerii.
Zdjęcia w galerii są co jakiś czas odświeżane bez przeładowania strony (właśnie po to korzystamy z AJAXa).
Brzmi ciekawie? To zapraszam do czytania dalej.
Etap pierwszy – utworzenie tabeli
Aby zacząć zabawę z naszą galerią, musimy najpierw stworzyć tabelę w bazie danych. Kod takiego zapytania MySQL generujący bazę danych wygląda następująco:
CREATE TABLE 'galeria' ( 'id_zdjecie' INT( 10 ) NOT NULL AUTO_INCREMENT , 'nazwa_zdjecie' VARCHAR( 255 ) DEFAULT NULL , 'opis_zdjecie' text, 'link_zdjecie' VARCHAR( 255 ) NOT NULL , PRIMARY KEY ( 'id_zdjecie' ) );
Czyli nic szczególnego.
Etap drugi – połączenie z bazą danych
Pierwszy etap za nami. Pora na napisanie kodu PHP udostępniającego połączenie z bazą danych:
db.php < ?php $dbhost = "adres_serwera"; $dbuser = "uzytkownik"; $dbpass = "haslo"; $dbname = "nazwa_bazy"; $mysqli = new MySQLi($dbhost, $dbuser, $dbpass, $dbname) or die(mysqli_error()); ?>
Bardzo często jako adres serwera wystarczy wpisać localhost.
Etap trzeci – tworzenie mechanizmu uploadu
Kolejnym krokiem jest stworzenie prostego formularza wysyłającego zdjęcia na serwer wraz z zapisaniem lokalizacji zdjęcia w bazie danych.

Najpierw wygląd formularza wysyłającego:
upload.php <h1>Upload zdjęcia do galerii</h1> <form action="upload.php?plik=dodaj" method="post" enctype="multipart/form-data" name="form1"> <input name="plik" type="file" size="50"/> <input name="max_file_size" type="hidden" value="2048576" /> <input value="Wyślij zdjęcie" type="submit" /> </form>
W formularzu wprowadziłem ograniczenie wielkości pliku do 1MB.
Teraz pora na kod przetwarzający dane z formularza i zapisujący wstępne dane do bazy MySQL:
< ?php if(isset($_GET['plik']) && $_GET['plik']=='dodaj') { $p_pojemnosc=$_FILES['plik']['size']; $p_typ=$_FILES['plik']['type']; if( strpos( $p_typ, 'image/jpeg' ) === false ) die( 'Wybrany plik nie plikiem jpg.' ); $p_nazwa=$_FILES['plik']['name']; $p_smiec=$_FILES['plik']['tmp_name']; $p_nazwa = strtolower($p_nazwa); $p_nazwa = str_replace("ż","z",$p_nazwa); $p_nazwa = str_replace("ą","a",$p_nazwa); $p_nazwa = str_replace(" ","",$p_nazwa); $p_nazwa = str_replace("_","",$p_nazwa); $p_nazwa = str_replace("ś","s",$p_nazwa); $p_nazwa = str_replace("ł","l",$p_nazwa); $p_nazwa = str_replace("ó","o",$p_nazwa); $p_nazwa = str_replace("ń","n",$p_nazwa); $p_nazwa = str_replace("ź","z",$p_nazwa); $p_nazwa = str_replace("ć","c",$p_nazwa); $p_nazwa = str_replace("ę","e",$p_nazwa); $sprawdzenia = substr($p_nazwa, strrpos($p_nazwa, ".")); $p_roz= array_pop(explode(".", $p_nazwa)); $max_size=round(($_POST['max_file_size']/2048576),3)."MB"; $poj_MB=round(($p_pojemnosc/2048576),2).'MB'; $p_nazwa_zm=(md5($p_nazwa)).".".$p_roz; $folder="img/"; if ($p_pojemnosc <= 0) { echo ("Plik jest pusty. Nie mogę go przesłać <b>".$p_nazwa." ".$poj_MB.$f_koniec.""); echo "<a href='upload.php'>Wracaj ...</a>"; exit; } if ($poj_MB > $max_size) { echo("Plik jest za duży. Maksymalnie można wysłać <b>".$max_size.$f_koniec."</b>"." .Plik wysyłany ma rozmiar <b><i>".$poj_MB.$f_koniec."</i></b>"); echo "<a href='upload.php'>Wracaj ...</a>"; exit; } if (file_exists($folder.$p_nazwa_zm)) { echo ("Plik o takiej nazwie jest już na serwerku <b><i>".$p_nazwa_zm."</i></b>"); echo "<a href='upload.php'>Wracaj ...</a>"; exit; } else { if(!move_uploaded_file($p_smiec, $folder.$p_nazwa_zm)) exit('Nie można zachować pliku. Prawdopodobnie nie ma folderu lub nie można w nim zapisać'); echo "Przesłanie udało się - <b>".$p_nazwa."</b>"." ".$poj_MB.""; $path_file=$folder.$p_nazwa_zm; require 'db.php'; $query = "INSERT INTO galeria (link_zdjecie) VALUES ('$path_file')"; $zapytanie = mysql_query($query); if(!$zapytanie) { echo "Wykonanie zapytania zawiodło. " . mysql_error(); } else { echo '<a href="upload.php?plik=opisz">Dodaj informacje o pliku</a>'; } } }
W powyższym kodzie PHP ma miejsce zamiany znaków diaktrycznych polskich na ich angielskie zamienniki, a także sprawdzenie czy plik nie jest za duży, czy zdjęcie jest w rozszerzeniem jpg oraz czy już przypadkiem nie istnieje zdjęcie o tej samej nazwie w folderze docelowym. Dodatkowo następuje szyfrowanie nazwy za pomocą MD5.
Po zakończeniu operacji dodawania zdjęcia do galerii wyświetla się komunikat, że można przejść do opisu zdjęcia.

Oto kod wyświetlający stronę z polami do opisu zdjęcia:
upload.php if(isset($_GET['plik']) && $_GET['plik']=='opisz') { echo ' <form method="post" action="upload.php?plik=dodajopis"> <label for="nazwa_zdjecie">Tytuł zdjęcia: </label> <input type="text" name="nazwa_zdjecie" id="nazwa_zdjecie"/> <label for="opis_zdjecie">Opis zdjęcia: </label> <textarea id="opis_zdjecie" name="opis_zdjecie" cols="50" rows="5"></textarea> <input value="Dodaj opis" type="submit" /> </form> '; }
Jest to po prostu wywołanie formularza za pomocą PHP. Kod przetwarzający dane z tego formularza wygląda następująco:
upload.php if(isset($_GET['plik']) && $_GET['plik']=='dodajopis') { require 'db.php'; $nazwa=$_POST['nazwa_zdjecie']; if(!empty($_POST['opis_zdjecie'])) { $opis=$_POST['opis_zdjecie']; } else { $opis='Brak opisu'; } if(empty($nazwa) || empty($opis)) { echo "Musisz wypełnić wszystkie pola"; exit; } $query="SELECT id_zdjecie, link_zdjecie FROM galeria ORDER BY id_zdjecie DESC LIMIT 1"; $wynik = mysql_query($query) or die(mysql_error()); if(!$wynik) { echo "Zapytanie nieudane. Nie można pobrać id zdjęcia. " . mysqli_error(); } else { $row = mysql_fetch_object($wynik); $id_zdjecie = $row->id_zdjecie; $path_file = $row->link_zdjecie; $sql = "UPDATE galeria SET nazwa_zdjecie='$nazwa', opis_zdjecie='$opis' WHERE id_zdjecie='$id_zdjecie'"; $zapytanie = mysql_query($sql); if(!$zapytanie) { echo "Wykonanie zapytania zawiodło. Nie można dodać informacji o filmie. " . mysqli_error(); } else { echo "Udało się dodać informacje o zdjęciu.Tytuł: ".$nazwa."Opis: ".$opis.""; echo '<img src="'.$path_file.'" width="320" class="demo" alt="" />'; } } }
Powyższy kod dodaje opis do zdjęcia, które przed chwilą zostało zapisane w bazie danych.

Na koniec jako potwierdzenie zapisu zostaje wywołany opis z bazy danych oraz zdjęcie, które zostało właśnie wstawione.
Ten mechanizm uploadu nie jest jakiś specjalnie zaawansowany, nie ma też zabezpieczeń przed atakami ze strony hakerów. Przykład ten ma tylko pokazać jak zbudować taki mechanizm, a od Twoich chęci będzie zależała kwestia bezpieczeństwa takiego formularza.
Etap czwarty – pobieranie danych do galerii
Teraz pora na stworzenie naszej galerii. Na początek musimy przygotować plik zczytujący dane z bazy danych i przetwarzający je na dane wejściowe do AJAXa.
Wygląda on tak:
json.php require 'db.php'; $query = "SELECT id_zdjecie, nazwa_zdjecie, opis_zdjecie, link_zdjecie FROM galeria ORDER BY Rand() LIMIT 4"; $result = mysql_query($query) or die(mysql_error($mysqli)); if ($result) { echo " <ul id='galeria'>"; while ($row = mysql_fetch_object($result)) { $nazwa = $row->nazwa_zdjecie; $opis = $row->opis_zdjecie; $link = $row->link_zdjecie; $id = $row->id_zdjecie; echo " <li><a href='$link' title='$nazwa'><img src='$link' alt='$title' /></a> <h4>$nazwa</h4> $opis </li> n"; } echo "</ul> "; }
Ma tutaj miejsce odczytywanie danych z bazy. Dodatkowo w zapytaniu MySQL jest funckaj Rand() która losowo wybiera 4 wiersze z bazy.
Etap piąty – wyświetlanie zdjęć w galerii
Takie dane przesyłamy do pliku index.php, gdzie znajduje się kod wyświetlający naszą galerię.
index.php
<h2>[PHP][MySQL][AJAX] Galeria zdjęć ze zmieniającymi się zdjęciami
demo by Piotr Nalepa</h2>
<div id="box">
<div id="galeria">
</div>
</div>Pewnie się teraz dziwisz, a gdzie tu jest AJAX? Heh, AJAX pojawia się w sekcji
naszej strony i wygląda on tak:function odswiezZdjecia() { $("#galeria").fadeOut(750, function() { $("#galeria").empty $("#galeria").load("json.php", function() { $("#galeria").fadeIn(); }); }); }; $(function(){ odswiezZdjecia(); var int = setInterval("odswiezZdjecia()", 6500); });
Dodatkowo należy pamiętać, że trzeba dołączyć bibliotekę jQuery do kodu pliku index.php, bo inaczej galeria nie będzie działać.
Na koniec przedstawię Ci jak wyglądają style dla takiej galerii:
img.demo { margin: 5px; border-top: 5px #fff solid; border-right: 5px #fff solid; border-left: 5px #fff solid; border-bottom: 50px #fff solid; } #galeria { margin-top: 0px; margin-right: auto; margin-bottom: 0px; margin-left: auto; padding: 10px; height: 100%; } #box { width: 620px; height: 200px; background-color: #333333; margin: 0 auto; padding-top: 20px; padding-right: 0px; padding-bottom: 20px; padding-left: 0px; border: 1px solid #999999; } #box ul { list-style: none; padding: 0px; margin: 0px; } #box li { display: block; float: left; width: 138px; text-align: center; overflow: hidden; margin: 0px; padding-top: 10px; padding-right: 5px; padding-bottom: 10px; padding-left: 5px; } #box li:hover { background-color: #666666; cursor:pointer; } #galeria h4 { padding: 0px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; color: #FFFFFF; font-size: 11px; } #galeria img { border: 1px solid #FFFFFF; margin: 0px; padding: 0px; width: 125px; height: auto; } #galeria p { font-size: 11px; margin: 0px; padding: 5px; color: #999999; font-weight: bold; }
Demo z tego artykułu jest dostępne tutaj: Galeria obrazków z użyciem AJAXa.
31 komentarze/y
Napisz komentarz
Komentarze są moderowane. Po akceptacji przez administratora zostaną wyświetlone na stronie.

22/01/2010 o 10:13
Świetna rzecz, efekt oszałamiający
Można wykorzystać na ogromną ilość sposobów. Dobra robota 
06/02/2010 o 18:50
W sumie mądrze piszesz:) Na tyle mądrze, że znalazło się dla Ciebie miejsce w moim google readerze
Pozdrawiam i czekam na kolejne wpisy
07/02/2010 o 17:40
Fajny artykuł.
Nie wiem tylko jak zrobić zatrzymanie odświeżania w momencie
najechania myszką na zdjęcie .
15/02/2010 o 21:58
Witam jak dlamnie to mniej więcej wiem o co chodzi .
ale jak to ma być z nazwami folderów np.install czy co tam
15/02/2010 o 23:08
Obrazki dajemy do folderu img, skrypty JavaScript dajemy do folderu js, a reszta plików zostaje w głównym katalogu.
To wszystko
15/03/2010 o 21:30
Idealnie działa. Jedyne co można poprawić, to dodawanie tytułu i opisu zdjęcia razem z samym zdjęciem.
Gratuluję pomysłu i wykonania.
01/06/2010 o 23:30
niestety za pomocą msqli nie mogę połączyć się z bazą danych……
Warning: mysql_query() [function.mysql-query]: Access denied for user ‘ODBC’@'localhost’ (using password: NO)
02/06/2010 o 07:17
a wpisujesz wszystko dokładnie tak jak w artykule?
bo jeśli tak, to powinno wszystko dobrze działać
02/06/2010 o 22:17
staram się
.. idę za listingami (pewnie źle): 1. tabela; 2. db.php; 3. upload.html; 4. upload.php; i…….. nie wiem gdzie wrzucić listing 4 (zapisujący wstępne dane do bazy ). reszta listingów jest opisana na górze
04/06/2010 o 14:49
jeśli podążałeś wedle listingów to powinieneś mieć dobrze
na chwilę obecną brakuje mi czasu aby się przyjrzeć temu problemowi, ale po 16-tym czerwca dam Ci odpowiedź co zrobiłeś źle
05/06/2010 o 14:08
witam! w pliku upload.php każde: galeria wystarczy zastąpić na: $dbname.galeria i przykład zaczyna działać, przynajmniej dodawanie zdjęć
24/06/2010 o 17:58
Jak zrobic,żeby zdjęcia sie dodawały,a przestały się zamieniać(losowe).
24/06/2010 o 22:48
nie do końca wiem, o co ci chodzi
11/09/2010 o 14:26
Witam,
Bardzo dobry tutorial. Niestety mam problem z poprawnym wyświetlaniem w przeglądarkach IE7 i IE8. Nie wiem jak ze starszymi, ale w reszcie typu Firefox, Chrom działa. Czy ktoś może zna przyczynę?
20/09/2010 o 11:30
U mnie też nie działa na IE dlaczego? Dajcie jakieś rozwiązanie.
20/09/2010 o 11:47
zaskakujące, postaram się znaleźć rozwiązanie do tego problemu w wolnej chwili
30/09/2010 o 19:11
mam problem skrypt pokazuje,że wybrany plik nie jest plikiem jpg.Co jest zle
30/09/2010 o 19:37
może problem jest z rozszerzeniem pliku?
może rozszerzenie jest pisane wielkimi literami?
30/09/2010 o 20:20
próbuje zmieniać wielkości liter i nie pomaga,jak zmienić to rozszerzenie tak aby działały także inne pliki. if( strpos( $p_typ, ‘images/JPG’ ) === false )
die( ‘Wybrany plik nie plikiem jpg.’ );
02/11/2010 o 22:34
Kurczę, chciałem się doczepić do bezpieczeństwa uploadu, a tu… Odnośnie sprawdzania typu pliku, to istnieje trochę więcej możliwości niż ‘image/jpeg’ – wystarczy wspomnieć choćby o ‘image/jpg’. Popróbuj sobie w różnych przeglądarkach, między Winem i Linuxem i zobaczysz, że część śle z jednym, a część z drugim typem MIME, a w specyfikacji istnieją jeszcze inne dla JPG. BTW jesteś pewien, że 2048576 to 1 MB? Jakoś mi się nie wydaje.
14/08/2011 o 20:18
Właściwie bawię się php ale jquery nawet nie liznąłem. Szukałem ciekawej galerii i ta mi się bardzo podoba ale niestety nie kumam gdzie i jakie biblioteki dodać i jak je wyegzekwować. Proszę o wyrozumiałość.
03/11/2011 o 22:53
Czy jest moze juz rozwiązanie problemu z wyświetlaniem w IE tych samych zdjęć. Zdaje się, że IE zapamiętuje plik json.php i nie czyta go ponownie. Czy można czyms wymusić na IE ponowne odczytanie tego pliku?
04/11/2011 o 00:11
Tutaj jest opisane rozwiazanie ale nie potrafie go wykorzystac w powyzszymm skrypcie. Jesli udaloby by sie to prosze o kontakt na maila
http://stackoverflow.com/questions/1061525/jquerys-load-not-working-in-ie-but-fine-in-firefox-chrome-and-safari
04/11/2011 o 09:22
Tak przy okazji w json.php nie jest przypisana zmienna $title
08/11/2011 o 19:45
ostatnio zmodyfikowałem nieco ten skrypt i w najbliższym czasie będzie jego aktualizacja
18/01/2012 o 16:05
witam mam taki błąd i nie mogę go usuna a wszystko wpisywalem dokladnie.
Warning: mysql_query() [function.mysql-query]: Access denied for user ‘root’@’62.146.68.219′ (using password: NO) in /srv/home/tpm10081/public_html/alert/galeria/upload.php on line 68
Warning: mysql_query() [function.mysql-query]: A link to the server could not be established in /srv/home/tpm10081/public_html/alert/galeria/upload.php on line 68
Wykonanie zapytania zawiodło. Access denied for user ‘root’@’62.146.68.219′ (using password: NO)
18/01/2012 o 21:27
Wygląda na to, że dane dostępu do serwera zostały źle podane. Należy wprowadzić poprawne i problem zniknie.
19/01/2012 o 12:03
Właśnie o to chodzi ze sa poprawne
19/01/2012 o 19:48
Skoro jest brak dostępu do serwera, to musi być coś źle z danymi dostępowymi. Proszę się upewnić.
20/01/2012 o 14:36
a ten cały kod trzeba wrzucić do upload.php razem z kodem przetwarzającym dane?
20/01/2012 o 15:26
Wiem w czym byl blad w moim przypadku.
w pliku upload.php
zamiast:
$mysqli = new MySQLi($dbhost, $dbuser, $dbpass, $dbname) or die(mysqli_error());
musialem zamienic na:
$mysqli = mysql_connect(‘localhost’,'tpm10081_paciak2′,’paciaki2′)
or die(‘Nieudane połączenie z bazą danych…’);
mysql_select_db(‘tpm10081_new’)
or die(‘Nie udało się wybrać bazy danych…’);
i dopiero zadziałało.
Dlaczego?