2009-03-17 33 views
52

En mi sitio web utilizo sesiones PHP. La información de la sesión se almacena en archivos en mi ruta ./session. Después de unos meses descubrí que estos archivos de sesión nunca se borran, ahora hay 145,000 de ellos en este directorio.limpiar archivos de sesión php

¿Cómo se deben limpiar? ¿Tengo que hacerlo programáticamente, o es una configuración que puedo usar en algún lugar que haría que esta limpieza se realice automáticamente?

EDIT se olvidó de mencionar: este sitio se ejecuta en un proveedor, por lo que no tengo acceso a una línea de comandos. Tengo ftp-access, pero los archivos de sesión pertenecen a otro usuario (el que ejecuta el servidor web, supongo). De las primeras respuestas que obtuve, creo que no se trata solo de una configuración en el servidor o PHP, así que supongo que lo haré. tiene que implementar algo para ello en PHP, y llamarlo periódicamente desde un navegador (tal vez desde un trabajo cron ejecutándose en mi propia máquina en casa)

Respuesta

51

Para manejar adecuadamente la sesión, echar un vistazo a http://php.net/manual/en/session.configuration.php.

Allí encontrará estas variables:

  • session.gc_probability
  • session.gc_divisor
  • session.gc_maxlifetime

Estos controlan el recolector de basura (GC) probabilidad de ejecución con cada solicitud de página.

Puede establecerlos con ini_set() al comienzo de la secuencia de comandos o el archivo .htaccess para obtener la certeza de que en cierta medida se eliminarán en algún momento.

+7

NOTA: Si está utilizando la opción de subdirectorio para almacenar archivos de sesión (consulte session.save_path arriba), entonces la recolección de basura * no * ocurre automáticamente. Tendrá que hacer su propia recolección de basura a través de un script de shell, entrada de cron o algún otro método. Por ejemplo, el siguiente script sería el equivalente a configurando session.gc_maxlifetime a 1440 (1440 segundos = 24 minutos): cd/path/to/sessions; encuentra -cmin +24 | xargs rm – Jehy

+0

@Jehy Parece que PHP ahora puede realizar la recolección de elementos no utilizados incluso cuando tiene una session.save_path personalizada. –

+0

@DarrellBrogdon ¿Tiene un recurso o más información sobre la recolección automática de basura de PHP cuando usa una ruta personalizada de session.save? Esto sería bueno si fuera el caso. – maartenmachiels

5

Utilice cron con find para eliminar archivos anteriores al umbral dado. Por ejemplo, para eliminar archivos a los que no se ha accedido durante al menos una semana.

find .session/ -atime +7 -exec rm {} \; 
+0

Gracias por su respuesta, como dije en la última versión de mi pregunta no es una opción para ejecutarla desde la línea de comandos, veré si puedo convencer a mi proveedor para que ponga algo como esto en el cron. – Jack

33

Debian/Ubuntu maneja esto con una tarea programada se define en /etc/cron.d/php5

# /etc/cron.d/php5: crontab fragment for php5 
# This purges session files older than X, where X is defined in seconds 
# as the largest value of session.gc_maxlifetime from all your php.ini 
# files, or 24 minutes if not defined. See /usr/lib/php5/maxlifetime 

# Look for and purge old sessions every 30 minutes 
09,39 *  * * *  root [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm 

El guión maxlifetime simplemente devuelve el número de minutos de una sesión debe ser mantenido con vida mediante la comprobación de php ini, parece que este

#!/bin/sh -e 

max=1440 

for ini in /etc/php5/*/php.ini; do 
     cur=$(sed -n -e 's/^[[:space:]]*session.gc_maxlifetime[[:space:]]*=[[:space:]]*\([0-9]\+\).*$/\1/p' $ini 2>/dev/null || true); 
     [ -z "$cur" ] && cur=0 
     [ "$cur" -gt "$max" ] && max=$cur 
done 

echo $(($max/60)) 

exit 0 
+0

Gracias por su respuesta Paul, como dije en la última versión de mi pregunta, no es una opción para ejecutarlo desde la línea de comando, veré si puedo convencer a mi proveedor para que ponga algo como esto en el cron. – Jack

+0

Gracias a esto, descubrí que alguien debe haber cortado y pegado esto a la ineficacia. El & en el comando ahora era &. El servidor no había recogido la basura por más de 2 años. ¡No me extraña que oliera tan mal por aquí! – flickerfly

+0

Entonces, ¿esto pasa por alto completamente todo lo que se establece a través de ini_set? No es de extrañar que configurar gc en el script no haga nada. – styks

2

Supongo que usted está en un servidor compartido y los archivos de sesión se mezclan entre todos los usuarios, por lo que no puede, ni debe, eliminarlos. Lo que puede hacer, si le preocupa la ampliación y/o la privacidad de la sesión de sus usuarios, es mover las sesiones a la base de datos.

Comience a escribir esa cookie en la base de datos y tendrá que recorrer un largo camino para escalar su aplicación en varios servidores cuando llegue el momento.

Aparte de eso, no me preocuparía mucho con los 145,000 archivos.

+0

Gracias Frankie, buena idea acerca de moverlo a la base de datos, lo tendrá en cuenta. – Jack

5

Puede crear /etc/cron.hourly/php guión y puso en su lugar:

#!/bin/bash 

max=24 
tmpdir=/tmp 

nice find ${tmpdir} -type f -name 'sess_*' -mmin +${max} -delete 

luego hacer el script ejecutable (chmod + x).

Ahora cada hora se eliminarán todos los archivos de sesión con datos modificados hace más de 24 minutos.

19

En caso de que alguien quiere es hacerlo con una tarea programada, por favor tenga en cuenta que esto:

find .session/ -atime +7 -exec rm {} \; 

es muy lento, al tener una gran cantidad de archivos.

Considere el uso de este lugar:

find .session/ -atime +7 | xargs -r rm 

En caso de que tenga espacios en los que los nombres de archivos usan este:

find .session/ -atime +7 -print0 | xargs -0 -r rm 

xargs se llenará la línea de comandos con los archivos que desea eliminar, a continuación, ejecutar el rm comando mucho menos que -exec rm {} \;, que llamará al comando rm para cada archivo.

Sólo mis dos centavos

+0

También tenga en cuenta que puede usar '-exec $ cmd {} +;' en lugar de '-exec $ cmd {} \;' Ejecutará todos los archivos encontrados dentro de un comando en lugar de ejecutar el comando una vez para cada archivo encontrado. Esto es muy similar a xargs como lo ha recomendado 'Andi'. Obtenga más información al respecto aquí: https://unix.stackexchange.com/questions/195939/what-is-meaning-of-in-finds-exec-command – domdambrogia

3
# Every 30 minutes, not on the hour<br> 
# Grabs maxlifetime directly from \`php -i\`<br> 
# doesn't care if /var/lib/php5 exists, errs go to /dev/null<br> 

09,39 * * * * find /var/lib/php5/ -type f -cmin +$(echo "\`php -i|grep -i session.gc_maxlifetime|cut -d' ' -f3\`/60" | bc) -exec rm -f {} \\; >/dev/null 2>&1 

el desglose: Sólo archivos: find/var/lib/php5/-type f
Mayor de minutos: -cmin
obtener configuración php : $ (echo "` php -i | grep -i session.gc_maxlifetime
Haz las cuentas: | cut -d '' -f3`/60 "| bc)
Archivos coincidentes RM: -exec rm -f {} \;

0

uso por debajo de cron:

39 20  * * *  root [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm 
0

cd al directorio de sesiones y luego:

1) Ver sesiones mayores de 40 min: find . -amin +40 -exec stat -c "%n %y" {} \;

2) Retire las sesiones mayores de 40 años min: find . -amin +40 -exec rm {} \;