Здравствуйте! Я разрабатываю админку, и передо мной стоит задача загрузки большого количества фотографий. Загружаемые изображения сохраняются в корневой директории сайта, но пути к этим изображениям необходимо отправить в базу данных. В настоящее время в базу данных попадает массив, вместо ожидаемой строки. Как мне исправить этот момент?
Вот пример кода, с которым я работаю:
<pre><code class="php">$uploaddir = "../uploads-gallery";
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["images"]["tmp_name"][$key];
// Функция basename() помогает защититься от атак на файловую систему;
// иногда требуется дополнительная проверка или очистка имени файла
$name = basename($_FILES["images"]["name"][$key]);
move_uploaded_file($tmp_name, "$uploaddir/$name");
}
};
$images = $_FILES["images"]["name"];</code></pre>
Проблема, с которой вы сталкиваетесь, заключается в том, что переменная `$images`, на которую ссылаются после выполнения цикла, содержит массив имен загруженных файлов. Чтобы сохранить пути к изображениям в базе данных, вам нужно преобразовать этот массив в строку.
Вот, как вы можете модифицировать ваш код, чтобы исправить это:
1. Создать новый массив для хранения полных путей к загруженным изображениям.
2. После загрузки каждого изображения добавлять его путь в этот массив.
3. После завершения цикла преобразовать массив в строку (например, с использованием функции `implode()`) для сохранения в базе данных.
Вот пример модифицированного кода:
```php
$uploaddir = "../uploads-gallery";
$imagePaths = []; // Массив для хранения путей к загруженным файлам
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["images"]["tmp_name"][$key];
$name = basename($_FILES["images"]["name"][$key]);
if (move_uploaded_file($tmp_name, "$uploaddir/$name")) {
// Добавляем путь к загруженному изображению в массив
$imagePaths[] = "$uploaddir/$name";
}
}
}
// Преобразуем массив путей в строку, разделенную запятыми
$imagePathsString = implode(',', $imagePaths);
// Теперь $imagePathsString можно сохранить в базу данных
```
### Замечания:
- Убедитесь, что путь к директории для загрузки существует и у PHP есть права на запись в эту директорию.
- Рекомендуется дополнительно проверять имя файла и файл перед его загрузкой (например, вы можете проверять расширение файла, размер файла и тип содержания).
- Если ваши изображения могут быть загружены с одинаковыми именами, стоит добавить уникальное идентификатор к имени файла, чтобы избежать перезаписи.
- После получения `$imagePathsString` вы можете использовать его в SQL-запросе для сохранения пути к изображениям в базе данных.
Смотрите, в переменной $images = $_FILES["images"]["name"]; находится массив. <br/> А поле в таблице у вас имеет формат text. <br/> PHP - не волшебник, он не понимает, в каком именно формате вам нужно запихнуть данные в это поле, и он пытается, как может, и пишет в дефолтном формате. <br/> <br/> Преобразование внутренних типов языка программирования в строки либо в те типы, которые понимает база данных, называется сериализацией. Т.е. нам надо PHP-шный массив преобразовать в тот формат в котором это поле в базе. <br/> <br/> Это можно сделать при помощи стандартной функции php <b>serialize</b> . <br/> <br/> <pre><code class="php">$images = $_FILES["images"]["name"]; $imagesSerialized = serialize($images); </code></pre> <br/> <br/> А когда вытащите содержимое из базы, то нужно будет использовать функцию <b>unserialize</b> <br/> <br/> Правда само содержимое в поле будет в специальном формате, и его будет трудно понимать, если будете своими глазами смотреть базу. Чтобы сделать это поле в базе более читаемым, ежели это вам надо, можно пойти двумя путями: <br/> <br/> 1. Вместо <b>serialize</b> - <b>unserialize</b> использовать <b>json_encode</b> и <b>json_decode</b> . Тогда в базе текст будет в джесончике, и его проще будет смотреть в базе. <br/> <br/> 2. Можно сделать еще лучше, и сделать само поле в базе в формате JSON (В MySQL и Postgres это точно есть.). И тогда можно будет использовать <b>json_encode</b> и <b>json_decode</b> . <br/> Чем это отличается от п.1? Тем, что можно будет использовать поля из такого объекта в запросах. Искать, менять и т.д.
Очевидно, что поле формы с множественной загрузкой файлов выдает массив, чтобы записать значения в базу надо всё-же : <br/> <pre><code class="php">$uploaddir = "../uploads-gallery";
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["images"]["tmp_name"][$key];
// Функция basename() помогает защититься от атак на файловую систему;
// иногда требуется дополнительная проверка или очистка имени файла
$name = basename($_FILES["images"]["name"][$key]);
move_uploaded_file($tmp_name, "$uploaddir/$name");
... функция записи в таблицу имени файла ($_FILES["images"]["name"][$key]);
}
};</code></pre>
Представим, что проблему сохранения вы как-то решили... А что вы намерены делать с сохранённым значением? <br/> <br/> Вариант 1 - всегда только извлекать весь массив целиком, в том виде, в каком он сохранялся. Никаких извлечений части массива, никаких по нему поисков, сортировок и прочего. Тогда преобразуйте массив во вменяемый сериализованный формат и сохраняйте в поле БД. <a href="https://qna.habr.com/user/vitiok78" rel="nofollow">Виктор Кожухарь</a> в своём ответе разобрал этот вариант. <br/> <br/> Вариант 2 - возможна какая-то обработка. Извлечение части массива по какому-то критерию (порядковый номер, соответствие шаблону и пр.), поиск в массиве по заданному критерию, сортировка самого массива либо массивов по какому-то критерию.. Тогда однозначно делите массив на отдельные элементы и сохраняйте их по одному (конечно, соответствующим образом должна измениться структура БД). Делить можно и на стороне PHP (как показывает <a href="https://qna.habr.com/user/cyber-jet" rel="nofollow">Евгений</a> в своём ответе), и в запросе на запись на стороне MySQL. Первое, как я понимаю, вам проще сделать, но правильно - второй вариант.