script - upload image php example
PHP organiza fotos cargadas (6)
Estoy construyendo una aplicación PHP que permite a los usuarios subir fotos. Para hacerlo manejable, una carpeta debe tener un máximo de 5000 fotos. A cada foto cargada se le asignará una ID en la base de datos, y la foto se renombrará como ID.
¿Cómo puedo verificar si una determinada carpeta tiene 5000 fotos? ¿Debo verificar la identificación de la última fila en la tabla de fotos?
Las carpetas se nombrarán incrementalmente. p.ej. folder_1
, folder_2
, etc.
Mis pasos propuestos:
- Recuperar el último ID de inserción de la tabla de fotos
- (Last_insert_ID + 1)% 5000 = Some_number (El número de la carpeta en la que debe guardarse)
- Guarde la foto en folder_some_number. Si la carpeta no existe, crea una nueva.
¿O hay una mejor manera de hacer esto?
El uso de la ID de inserción puede no ser muy preciso, ya que existe una serie de condiciones de error que pueden causar que se "salte" una identificación. Puede guardar el número de carpeta en una columna separada, llamada "folder_number" o similar. De esta forma puede obtener el número de carpeta más alto y luego contar el número de registros en esa carpeta, si es menor que 5000, agregarlo en la misma carpeta; de lo contrario, ejecute su lógica para incrementar el número de carpetas (creando el físico carpeta al mismo tiempo).
Eso debería ser más rápido que usar el sistema de archivos para verificar, que podría ser bastante lento para el volumen de archivos de los que está hablando.
No use identificadores de autoincrement para hacer cálculos. Cuando elimines archivos, obtendrás agujeros en tus secuencias de ID que te quitarán las matemáticas. Guarde el filepath en su tabla db. Luego haz un simple COUNT:
SELECT filepath, COUNT(filename) AS num FROM mytable
GROUP BY filepath;
Puede guardar nuevos archivos en filepaths donde num <5000.
Permítanme sugerir otro enfoque: use un hash en la identificación de la imagen y use los primeros caracteres como una ruta, por ejemplo, supongamos que la ID de la imagen es 1 para la cual el hash es c4ca4238a0b923820dcc509a6f75849b
. Cree la estructura de directorio /rootpath/images/c/4/c/
y en ella guarde la imagen. Puede usar mkdir()
para crear directorios anidados como mkdir( ''/dir/c/4/c/'', 0777, true );
.
De esta forma, distribuye automáticamente la carga entre muchas carpetas y la propia ID es la ruta.
Si mi memoria sirve, WordPress usa algo similar ...
Supongo que las lecturas de la base de datos van a ser más rápidas que las lecturas del sistema de archivos como esta.
Sería mejor ejecutar una consulta sql y obtener un recuento por carpeta, agrupado.
// 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;
Nota: si necesita muestras de código reales, puedo acelerar algo rápidamente. Los ejemplos anteriores dejan fuera el código de trabajo real y son solo para fines teóricos. Tendrá que recorrer las filas devueltas, ya que están agrupadas por carpeta.
si desea organizar sus carpetas y archivos de esta manera, no necesita verificar si la carpeta tiene 5000 archivos, simplemente asigne los archivos a la carpeta correspondiente.
Si hay menos de 5000 archivos en la carpeta de hax que deberían estar llenos (debido a que el último ID es más grande que 5000 * x) eso significa que se han eliminado algunas imágenes. No puede reasignar esa ID a una fila en su base de datos para que no pueda volver a llenar el espacio de los archivos eliminados.
$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