chevron-left chevron-right

Piotr Nalepa Frontend, architecture and AI

[PHP][JS] Galeria zdjęć ze zmieniającymi się zdjęciami + upload zdjęć na serwer

This version
blog.piotrnalepa.pl/2010/01/16/php-js-galeria-zdjec-ze-zmieniajacymi-sie-zdjeciami-upload-zdjec-na-serwer
Published
Author
, Staff Software Engineer
Categories
JavaScript, PHP
Feedback
Write to me · Post on X

This post is 16 years old. Browsers and tools may have changed since then, so check the code against current documentation before you use it.

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.

Section 1Etap 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:

Example 1SQL
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.

Section 2Etap drugi - połączenie z bazą danych

Pierwszy etap za nami. Pora na napisanie kodu PHP udostępniającego połączenie z bazą danych:

Example 2PHP
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.

Section 3Etap 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:

Example 3HTML
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:

Example 4PHP
< ?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 "Wracaj ...";
			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 "Wracaj ...";
			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 "Wracaj ...";
			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 'Dodaj informacje o pliku';
            }
		}
	}

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:

Example 5PHP
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:

Example 6PHP
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.

Section 4Etap 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:

Example 7PHP
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>
<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.

Section 5Etap piąty - wyświetlanie zdjęć w galerii

Takie dane przesyłamy do pliku index.php, gdzie znajduje się kod wyświetlający naszą galerię.

Example 8HTML
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:

Example 9JavaScript
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:

Example 10CSS
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.

Share
Feedback

About the author

Staff Software Engineer

I've been writing this blog since 2009 and building for the web professionally for 14 years. Today I lead the frontend of the Cosmos platform at Bishop Fox, where I've been since day one of the project. Before that I worked at OLX, KUDO, Auto1 and eZ Systems. Here I write about what I've learned in practice: JavaScript, TypeScript, React, CSS and frontend architecture. I've also spoken at conferences across Poland and Europe. Got a question or an idea for a post? Let me know!