PHP организовать загруженные фотографии

Я создаю приложение PHP, которое позволяет пользователям загружать фотографии. Для удобства в папке должно быть не более 5000 фотографий. Каждой загруженной фотографии будет присвоен идентификатор в базе данных, а фотография будет переименована в идентификатор.

Как проверить, есть ли в определенной папке 5000 фотографий? Должен ли я проверить ID последней строки в таблице фотографий?

Папки должны называться постепенно. например. folder_1, folder_2, так далее.

Мои предлагаемые шаги:

  1. Получить последнюю вставку ID таблицы фотографий
  2. (Last_insert_ID + 1) % 5000 = Some_number (номер папки, в которой он должен быть сохранен)
  3. Сохранить фотографию в folder_some_number. Если папка не существует, создайте новую.

Или есть лучший способ сделать это?

6 ответов

Решение
$last_id; // for example 9591
$current_folder = floor($last_id/5000);
$picture_num_in_folder = $last_id-($current_folder*5000);
if ($picture_num_in_folder == 5000)
    // new dir and such (new folderid = $current_folder+1 and $picture_num_in_folder = 1)
else
    // just place the picture with unique ID $last_id+1 called image_$picture_num_in_folder+1 in folder $current_folder

Я предполагаю, что чтение из базы данных будет быстрее, чем чтение файловой системы, как это.

Было бы лучше выполнить SQL-запрос и получить счетчик для каждой папки, сгруппированный.

// Example Query
SELECT COUNT(file), folderId As Count FROM photos WHERE folderId IN ('1', '2') GROUP BY folder
// It would be beneficial to have a flag on the folders that would enable or disable them
// that way you're not iterating through folders that we already know are > 5k
// You would run this and have seperate query that would pull in these folder names
// and passing them to the above query.
SELECT foldername, folderId FROM folders WHERE countFlag = 0;


//Example Conditional.
if($Count > 5000):
  // Over 5k Do Something
  //Since were over 5k, set this folders flag to 1
  // that way we arent iterating through it again
  $countFlag = 1;
else:
  // Under 5k Do Something else
endif;

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

Не используйте автоинкрементные идентификаторы для расчетов. Когда вы удаляете файлы, вы получите дыры в ваших последовательностях ID, которые отбросят вашу математику. Сохраните путь к файлу в вашей таблице базы данных. Затем сделайте простой подсчет:

SELECT filepath, COUNT(filename) AS num FROM mytable
GROUP BY filepath;

Вы можете сохранять новые файлы в filepaths, где num < 5000.

Использование идентификатора вставки может быть не очень точным, поскольку существует ряд ошибок, которые могут привести к пропуску идентификатора. Вы можете хранить номер папки в отдельном столбце, называемом "folder_number" или подобным. Таким образом, вы можете получить наибольший номер папки, а затем подсчитать количество записей в этой папке, если оно меньше 5000, добавить его в ту же папку, в противном случае запустить вашу логику, чтобы увеличить количество папок (создание физического папка одновременно).

Это должно быть быстрее, чем проверка файловой системы, что может быть довольно медленным для объема файлов, о которых вы говорите.

Позвольте мне предложить другой подход: использовать хеш для идентификатора изображения и использовать первые несколько символов в качестве пути, например, предположим, что идентификатор изображения равен 1, для которого хэш c4ca4238a0b923820dcc509a6f75849b, Создать структуру каталогов /rootpath/images/c/4/c/ и в нем сохраните изображение. Ты можешь использовать mkdir() создавать вложенные каталоги, такие как mkdir( '/dir/c/4/c/', 0777, true );,

Таким образом, вы автоматически распределяете нагрузку по многим папкам, а сам идентификатор является путем.

Если мне не изменяет память, WordPress использует нечто подобное...

Если вы хотите организовать ваши папки и файлы таким образом, вам не нужно проверять, есть ли в папке 5000 файлов, просто назначьте файлы соответствующей папке.

Если в папке a x содержится менее 5000 файлов, которые должны быть заполнены (поскольку последний идентификатор больше 5000*x), это означает, что некоторые изображения были удалены. Вы не можете переназначить этот идентификатор в строку в вашей базе данных, поэтому вы не можете заполнить пространство удаленных файлов.

Другие вопросы по тегам