Да, да, я знаю, что это древняя тема. Но проблема в хранении большого количества изображений и в том, как должна быть организована основная структура папок. Поэтому я представляю свой способ справиться с этим в надежде, что это может помочь некоторым людям.
Идея использования хеша md5 - лучший способ хранения больших массивов изображений. Помня о том, что разные значения могут иметь один и тот же хеш, я настоятельно рекомендую добавить к пути также идентификатор пользователя или ник, чтобы сделать его уникальным. Да, это все, что нужно. Если у кого-то есть разные пользователи с одним и тем же идентификатором базы данных - хорошо, что-то не так;) Так что root_path/md5_hash/user_id
- это все, что вам нужно для правильной работы.
Использование DATE / DATETIME / TIMESTAMP, кстати, не является оптимальным решением для IMO. В результате вы получаете большие скопления папок с изображениями в день покупки и почти пустые в менее посещаемых. Не уверен, что это приводит к проблемам с производительностью, но есть что-то вроде эстетики данных, и последовательное распределение данных всегда лучше.
Так что я, безусловно, иду к решению хэша.
Я написал следующую функцию, чтобы упростить создание таких путей хранения на основе хеша. Не стесняйтесь использовать его, если вам это нравится.
/**
* Generates directory path using $user_id md5 hash for massive image storing
* @author Hexodus
* @param string $user_id numeric user id
* @param string $user_root_raw root directory string
* @return null|string
*/
function getUserImagePath($user_id = null, $user_root_raw = "images/users", $padding_length = 16,
$split_length = 3, $hash_length = 12, $hide_leftover = true)
{
// our db user_id should be nummeric
if (!is_numeric($user_id))
return null;
// clean trailing slashes
$user_root_rtrim = rtrim( $user_root_raw, '/\\' );
$user_root_ltrim = ltrim( $user_root_rtrim, '/\\' );
$user_root = $user_root_ltrim;
$user_id_padded = str_pad($user_id, $padding_length, "0", STR_PAD_LEFT); //pad it with zeros
$user_hash = md5($user_id); // build md5 hash
$user_hash_partial = $hash_length >=1 && $hash_length < 32
? substr($user_hash, 0, $hash_length) : $user_hash;
$user_hash_leftover = $user_hash_partial <= 32 ? substr($user_hash, $hash_length, 32) : null;
$user_hash_splitted = str_split($user_hash_partial, $split_length); //split in chunks
$user_hash_imploded = implode($user_hash_splitted,"/"); //glue aray chunks with slashes
if ($hide_leftover || !$user_hash_leftover)
$user_image_path = "{$user_root}/{$user_hash_imploded}/{$user_id_padded}"; //build final path
else
$user_image_path = "{$user_root}/{$user_hash_imploded}/{$user_hash_leftover}/{$user_id_padded}"; //build final path plus leftover
return $user_image_path;
}
Функциональные тестовые вызовы:
<code>$user_id = "1394";
$user_root = "images/users";
$user_hash = md5($user_id);
$path_sample_basic = getUserImagePath($user_id);
$path_sample_advanced = getUserImagePath($user_id, "images/users", 8, 4, 12, false);
echo "<pre>hash: {$user_hash}
";
echo "
basic:<br>{$path_sample_basic}
";
echo "
customized:<br>{$path_sample_advanced}
";
эхо "
";
Полученный вывод - раскрашен для вашего удобства;):