Компьютеры
и программирование

Безопасная загрузка картинок на сайт

Существует много решений для загрузки картинок на сайт, простых и не очень. Есть разница – загружаете ли Вы картинки на свой собственный сайт через админку или же картинки загружают пользователи сайта. У некоторых пользователей есть соблазн загрузить на сайт нежелательные для Вас файлы, которые могут навредить сайту. В этой статье рассказывается, как сделать на PHP загрузку картинок на сайт пользователями, а значит, предлагаемая система должна предотвращать загрузку вместо картинок нежелательных файлов. Можно пользоваться кодом из листингов, чтобы вставить его на свой сайт, ну, а если Вы хотите понять, как всё это работает, придётся покопаться в коде, а его, кода, в этой статье будет много.

Начинаем с создания базы данных или таблицы уже существующей базы данных. Таблица будет называться “people”.

Код MySQL

CREATE TABLE `people` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `fname` VARCHAR( 30 ) NOT NULL , `lname` VARCHAR( 40 ) NOT NULL , `filename` VARCHAR( 50 ) NOT NULL ) ENGINE = MYISAM ;

Далее строим структуру каталогов. У нас будет корневая папка, которая содержит все подкаталоги, а также файлы PHP. В корневом каталоге размещёны подкаталог с названием “images” и подкаталог с названием “includes”. В результате получается структура, которая выглядит следующим образом.

Код PHP

root-directory/images.php root-directory/index.php root-directory/upload.php root-directory/images/ root-directory/includes/conn.php

В файл includes/conn.php нужно вставить следующий код:

Код PHP

<?php // ввод информации для базы данных // имя хоста $host = "localhost"; // имя пользователя базы данных $username = "username"; // пароль базы данных $password = "password"; // название базы данных $database = "db_name"; $conn = mysql_connect($host, $username, $password)or die ("Нет соединения"); $db = mysql_select_db($database, $conn) or die("Не выбрана база данных"); ?>

Теперь создаём файл index. Он содержит просто форму с тремя полями: имя, фамилия и картинка. Здесь предложен и некий стиль CSS, но Вы можете использовать и свой.

Код HTML/PHP

<?php // начало сессии и отображение ошибок session_start(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Загрузка картинок на сайт</title> <style type="text/css"> label { float: left; text-align: right; margin-right: 10px; width: 100px; color: black; } #submit { float: left; margin-top: 5px; position: relative; left: 110px; } #error { color: red; font-weight: bold; font-size: 16pt; } </style> </head> <body> <div> <?php if (isset($_SESSION['error'])) { echo "<span id=\"error\"><p>" . $_SESSION['error'] . "</p></span>"; unset($_SESSION['error']); } ?> <form action="upload.php"method="post" enctype="multipart/form-data"> <p> <label>Имя</label> <input type="text"name="fname" /><br /> <label>Фамилия</label> <input type="text"name="lname" /><br /> <label>Загружаемая картинка</label> <input type="file"name="image" /><br /> <input type="hidden"name="MAX_FILE_SIZE" value="100000" /> <input type="submit"id="submit" value="Загрузить" /> </p> </form> </div> </body> </html>

Сейчас последует очень важная часть кода. Весь код снабжён комментариями, из которых Вам должно быть понятно, как всё это работает.

Код PHP

<?php // начало сессии и сообщения об ошибках session_start(); // вызов файла соединения с базой данных require("includes/conn.php"); // Проверка, является ли тип загруженного файла допустимым типом изображения function is_valid_type($file) { // массив, содержащий все допустимые типы файлов изображений $valid_types = array("image/jpg","image/jpeg", "image/bmp", "image/gif"); if (in_array($file['type'], $valid_types)) return 1; return 0; } // короткая функция, которая распечатывает содержание массива способом, при котором его легко прочитать // можно использовать эту функцию во время отладки, но ей можно пренебречь во время работы скрипта function showContents($array) { echo "
";
	    print_r($array);
	    echo "
"; } // определение некоторых констант // в этой переменной - путь к папке изображений, в которой все изображения будут сохраненными // обратите внимание на слэш $TARGET_PATH = "images/"; // получение отправленных переменных $fname = $_POST['fname']; $lname = $_POST['lname']; $image = $_FILES['image']; // очистка введённых данных $fname = mysql_real_escape_string($fname); $lname = mysql_real_escape_string($lname); $image['name'] = mysql_real_escape_string($image['name']); // Построение пути, по которому файл будет перемещен // т.e. images/picture.jpg $TARGET_PATH .= $image['name']; // проверка, заполнены ли все поля формы if ( $fname == "" || $lname == "" ||$image['name'] == "" ) { $_SESSION['error'] = "Все поля должны быть заполнены"; header("Location: index.php"); exit; } // проверка, является ли загружаемый файл изображением // проверяется тип файла, а не расширение, поскольку расширение легко сфальсифицировать if (!is_valid_type($image)) { $_SESSION['error'] = "Вы можете загружать файлы jpeg, gif, bmp"; header("Location: index.php"); exit; } // проверка, нет ли в базе данных файла с таким же названием // устранение проблем с названием с использованием метки времени if (file_exists($TARGET_PATH)) { $_SESSION['error'] = "Файл с таким именем уже существует"; header("Location: index.php"); exit; } // перемещение файла из временного хранилища в постоянное if (move_uploaded_file($image['tmp_name'],$TARGET_PATH)) { // ВНИМАНИЕ: это место, где очень многие делают ошибки // мы не вставляем изображение в базу данных; мы вставляем ссылку на расположение файла на сервере $sql = "insert into people (fname, lname, filename) values ('$fname', '$lname', '" .$image['name'] . "')"; $result = mysql_query($sql) or die ("Невозможно вставить данные в базу: " . mysql_error()); header("Location: images.php"); exit; } else { // частая причина неудачи в продвижении файла в ошибке в правах доступа к директории, нужны права на запись // установите для директории права доступа с записью $_SESSION['error'] = "Невозможно загрузить файл. Проверьте права доступа к директории (чтение/запись)"; header("Location: index.php"); exit; } ?>

Одно из условий в коде выше является предметом вопроса в Тесте по теме Программирование PHP/MySQL.

Наш скрипт содержит функцию, которая проверяет, относится ли загружаемый файл к допустимым типам файлов. Это предотвращает загрузку различных исполняемых файлов и других вредных файлов. Следующая функция используется для отладки. Далее следует проверка, не является ли какое-либо из полей, предназначенных для заполнения, пустым. Есть также проверка, нет ли среди уже хранимых в базе названий файлов название нового загружаемого файла. И, наконец, загруженный файл перемещается в каталог. Информация заносится в базу данных. Все загруженные картинки будут отображаться на странице images.php или любой другой странице с названием по Вашему усмотрению.

Код HTML/PHP

<?php // включение файла соединения с базой данных require("includes/conn.php"); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Список картинок</title> </head> <body> <div> <span class="pm2"><?php // получение данных из таблицы people $sql = "select * from people"; $result = mysql_query($sql) or die ("Нет соединения с базой данных: " . mysql_error()); while ($row = mysql_fetch_assoc($result)) { echo "<div class=\"picture\">"; echo "<p>"; // строим последовательность src, используя название файла из базы данных echo "<img src=\"images/" .$row['filename'] . "\" alt=\"\" /><br />"; echo $row['fname'] . " " .$row['lname'] . "<br />"; echo "</p>"; echo "</div>"; } ?> </div> </body> </html>

Итак, загрузка картинок на сайт и хранение их данных в базе готовы!

Поделиться с друзьями