chevron-left chevron-right

Piotr Nalepa Frontend, architektura i AI

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

Ta wersja
blog.piotrnalepa.pl/2010/01/16/php-js-galeria-zdjec-ze-zmieniajacymi-sie-zdjeciami-upload-zdjec-na-serwer
Opublikowano
Autor
, Staff Software Engineer
Kategorie
JavaScript, PHP
Uwagi
Napisz do mnie · Napisz na X

Ten wpis ma 16 lat. Od tego czasu przeglądarki i narzędzia mogły się zmienić, więc zanim użyjesz kodu, sprawdź go z aktualną dokumentacją.

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.

Sekcja 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:

Przykład 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.

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

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

Przykład 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.

Sekcja 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:

Przykład 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:

Przykład 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:

Przykład 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:

Przykład 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.

Sekcja 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:

Przykład 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.

Sekcja 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ę.

Przykład 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:

Przykład 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:

Przykład 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.

Udostępnij
Uwagi

O autorze

Staff Software Engineer

Piszę na tym blogu od 2009 roku, a strony i aplikacje webowe tworzę zawodowo od 14 lat. Obecnie w Bishop Fox prowadzę frontend platformy Cosmos, od samego początku projektu. Wcześniej pracowałem m.in. w OLX, KUDO, Auto1 i eZ Systems. Piszę tu o tym, czego nauczyłem się w praktyce: o JavaScripcie, TypeScripcie, Reakcie, CSS-ie i architekturze frontendu. Występowałem też jako prelegent na konferencjach w Polsce i Europie. Masz pytanie albo pomysł na wpis? Daj znać!