Fisiere stocate in baza de date cu PHP si MySQL
In continuare voi prezenta un mic tutorial despre stocarea fisierelor in baza de date.
Cand avem nevoie de stocarea fisierelor in baza de date? Un scenariu bun este atunci cand fisierele sunt confidentiale.
Dezavantajul principal este viteza de acces, cat timp mai este si o baza de date la mijloc asta va intarzia procesul de regasire/afisare.
Structura bazei de date:
1CREATE TABLE IF NOT EXISTS fisiere (
2 ID int(10) unsigned NOT NULL AUTO_INCREMENT,
3 nume varchar(255) NOT NULL,
4 tip varchar(255) NOT NULL,
5 marime int(11) NOT NULL,
6 fisiere longblob NOT NULL,
7 timp int(11) DEFAULT NULL,
8 PRIMARY KEY (`ID`)
9) ENGINE=MyISAM
Trebuie sa stocam tipul, marimea si continutul fisierului propriuzis. Numele este retinut mai mult pt extensie.
Conectarea la baza de date:
1<?php
2// db.php
3mysql_connect('localhost', 'user', 'parola');
4mysql_select_db('fisiere');
5
6// am omis intentionat tag-ul de inchis pt PHP
7// ca sa am certitudinea ca nu se trimit headere
Fisierul de upload si listare:
In acest fisier se afla adaugare, stergerea si listarea fisierelor din baza de date
1<?php
2// legatura la baza de date
3include('db.php');
4
5// mesaj de eroare
6$errmsg = NULL;
7
8// stergerea fisierului din BD
9if(isset($_GET['del']))
10{
11 $qr="DELETE FROM fisiere WHERE ID='".mysql_escape_string($_GET['del'])."'";
12 if(!mysql_query($qr)) {
13 $errmsg = 'Fisierul nu a putut fi sters!<br>';
14 }
15}
16
17// verificam daca a fost trimis un fisier si are diminesiunea mai mare de 0
18if($_FILES['fisier']['size'] > 0) {
19
20 // se citeste continutul fisierului
21 $content = file_get_contents($_FILES['fisier']['tmp_name']);
22
23 // se codeaza cu base64_encode pt a nu aparea probleme la caractere speciale
24 //si se sparge in bucati
25 $content = chunk_split(base64_encode($content));
26
27 // se introduc datele in baza de date
28 $qr="INSERT INTO fisiere SET
29 nume ='".mysql_escape_string($_FILES['fisier']['name'])."',
30 tip ='".mysql_escape_string($_FILES['fisier']['type'])."',
31 marime ='".mysql_escape_string($_FILES['fisier']['size'])."',
32 fisiere='".$content."',
33 timp ='".time()."'";
34
35 // se verifica daca datele au fost inserate cu succes
36 if(mysql_query($qr)) {
37 // daca datele au fost stocare cu succes se face refres la pagina
38 // pentru a evita cazul in care utilizatorul apasa "refresh"
39 header("Location: ".$PHP_SELF."?ok=1");
40 exit();
41 } else {
42 $errmsg = 'Eroare la upload<br>';
43 }
44
45}
46?>
47<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
48"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
49<html xmlns="http://www.w3.org/1999/xhtml">
50<head>
51<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
52<title>Fisiere</title>
53</head>
54
55<body>
56<?php
57if($_GET['ok']==1) echo "fisierul a fost incarcat!";
58// afisaza mesajul de eroare daca acesta exista
59if($errmsg) echo $errmsg;
60?>
61
62<?php
63// selecteaza fisierele din BD
64$qr="SELECT * FROM fisiere ORDER BY timp";
65$rez=mysql_query($qr);
66if(mysql_num_rows($rez)>0) {
67?>
68<table border="1">
69 <tr>
70 <td>ID</td>
71 <td>Nume</td>
72 <td>Ora</td>
73 <td>Descarca</td>
74 <td>sterge</td>
75 </tr>
76 <?php
77 while($row=mysql_fetch_array($rez)) {
78 ?>
79 <tr>
80 <td><?php echo $row["ID"]; ?></td>
81 <td><?php echo $row["nume"]; ?></td>
82 <td><?php echo date("d-m-Y",$row["timp"]); ?></td>
83 <td><a href="descarca.php?ID=<?php echo $row["ID"]; ?>">descarca fisier</a></td>
84 <td>
85 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?del=<?php echo $row["ID"] ?>"
86 onclick="return confirm('doriti sa stergeti acest fisier?');">
87 sterge
88 </a>
89 </td>
90 </tr>
91 <?php } ?>
92</table>
93<?php
94} else {
95 echo "nu exista fisiere in baza de date!";
96}
97?>
98<br />
99<br />
100<form method="post" enctype="multipart/form-data"
101 action="<?php echo $_SERVER['PHP_SELF']; ?>">
102<input type="file" name="fisier" />
103<input type="submit" value="Incarca" />
104</form>
105</body>
106</html>
Descarcarea fisierului:
1<?php
2include('db.php');
3
4// selectarea fisierului din BD
5$qr="SELECT * FROM fisiere WHERE ID='".mysql_escape_string($_GET['ID'])."'";
6$rez=mysql_query($qr);
7$row=mysql_fetch_array($rez);
8
9$size = $row['marime'];
10$type = $row['tip'];
11$name = $row['nume'];
12$fisiere = $row['fisiere'];
13
14// dezactivam compresia pt ca nu aparea erori la afisare
15if(ini_get('zlib.output_compression'))
16ini_set('zlib.output_compression', 'Off');
17
18// fisierul trebuie descarcat de pe server nu din cache
19header("Pragma: public");
20header("Expires: 0");
21header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
22header("Cache-Control: private",false);
23
24// dimensiunea fisierului
25header("Content-length: ".$size);
26
27// tipul fisierului
28header("Content-Type: ".$type);
29
30// optional daca dorim sa forteze download-ul
31header("Content-Type: application/force-download");
32
33// numele fisierului cu care va fi salvat pe disk
34header("Content-Disposition: attachment; filename=\"".$name."\";");
35
36// transfer binar pt a evita caracterele speciale
37header("Content-Transfer-Encoding: binary");
38
39// decodam continutul fisierului si il afisam
40echo base64_decode($fisiere);
41
42?>
Dupa cum se poate vedea serverul are destul de multe lucruri de facut pentru a afisa un simplu fisier, de asta nu este bine sa fie stocate pe disk toate fisierele, ar fi o risipa de resurse. Pe de alta parte, fisierele private (cum ar fi cartile digitale sau melodiile) sunt clienti ideali pentru aceasta forma de stocare.