After having many problems with garbage collection not clearing my sessions I have resolved it through the following.
First I found this in the php.ini (not something i noticed as i use phpinfo(); to see my hosting ini).
; NOTE: If you are using the subdirectory option for storing session files
; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method. ; For example, the following script would is the equivalent of
; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; cd /path/to/sessions; find -cmin +24 | xargs rm
With this is mind there are options.
1. dont use a custom save_path.
** This means if your isp hasnt defaulted your session temp to something safer than install default or you are using a shared directory for session data then you would be wise to use named sessions to keep your session from being viewable in other people's scripts. Creating a unique_id name for this is the common method. **
2. use your custom folder but write a garbage collection script.
3. use a custom handler and a database
Configuración en tiempo de ejecución
El comportamiento de estas funciones se ve afectado por la configuración de php.ini.
| Nombre | Por defecto | Cambiable | Historial de cambios |
|---|---|---|---|
| session.save_path | "" | PHP_INI_ALL | |
| session.name | "PHPSESSID" | PHP_INI_ALL | |
| session.save_handler | "files" | PHP_INI_ALL | |
| session.auto_start | "0" | PHP_INI_ALL | |
| session.gc_probability | "1" | PHP_INI_ALL | |
| session.gc_divisor | "100" | PHP_INI_ALL | Disponible desde PHP 4.3.2. |
| session.gc_maxlifetime | "1440" | PHP_INI_ALL | |
| session.serialize_handler | "php" | PHP_INI_ALL | |
| session.cookie_lifetime | "0" | PHP_INI_ALL | |
| session.cookie_path | "/" | PHP_INI_ALL | |
| session.cookie_domain | "" | PHP_INI_ALL | |
| session.cookie_secure | "" | PHP_INI_ALL | Disponible desde PHP 4.0.4. |
| session.cookie_httponly | "" | PHP_INI_ALL | Disponible desde PHP 5.2.0. |
| session.use_cookies | "1" | PHP_INI_ALL | |
| session.use_only_cookies | "1" | PHP_INI_ALL | Disponible desde PHP 4.3.0. |
| session.referer_check | "" | PHP_INI_ALL | |
| session.entropy_file | "" | PHP_INI_ALL | |
| session.entropy_length | "0" | PHP_INI_ALL | |
| session.cache_limiter | "nocache" | PHP_INI_ALL | |
| session.cache_expire | "180" | PHP_INI_ALL | |
| session.use_trans_sid | "0" | PHP_INI_ALL | PHP_INI_ALL en PHP <= 4.2.3. PHP_INI_PERDIR en PHP < 5. Disponible desde PHP 4.0.3. |
| session.bug_compat_42 | "1" | PHP_INI_ALL | Disponible desde PHP 4.3.0. Eliminado en PHP 5.4.0. |
| session.bug_compat_warn | "1" | PHP_INI_ALL | Disponible desde PHP 4.3.0. Eliminado en PHP 5.4.0. |
| session.hash_function | "0" | PHP_INI_ALL | Disponible desde PHP 5.0.0. |
| session.hash_bits_per_character | "4" | PHP_INI_ALL | Disponible desde PHP 5.0.0. |
| url_rewriter.tags | "a=href,area=href,frame=src,form=,fieldset=" | PHP_INI_ALL | Disponible desde PHP 4.0.4. |
| session.upload_progress.enabled | "1" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
| session.upload_progress.cleanup | "1" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
| session.upload_progress.prefix | "upload_progress_" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
| session.upload_progress.name | "PHP_SESSION_UPLOAD_PROGRESS" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
| session.upload_progress.freq | "1%" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
| session.upload_progress.min_freq | "1" | PHP_INI_PERDIR | Disponible desde PHP 5.4.0. |
El sistema de administración de sesiones soporta varias opciones de configuración que se pueden colocar en el archivo php.ini. Se dará una visión general breve.
-
session.save_handlerstring - session.save_handler define el nombre del gestor que se usa para almacenar y recuperar información asociada con una sesión. Por defecto es files. Observe que las extensiones individuales pueden registrar sus propios gestores save_handler; los gestores registrados se pueden obtener a nivel de instalación consultando phpinfo(). Véase también session_set_save_handler().
-
session.save_pathstring -
session.save_path define el argumento que
es pasado al gestor de almacenamiento. Si se elige el gestor de archivos
por defecto, éste es la ruta donde los archivos son creados. Véase también
session_save_path().
Hay un argumento opcional N para esta directiva que determina el número de niveles de directorios por donde los archivos de sesión se desplegarán. Por ejemplo, establecerlo a '5;/tmp' puede terminar en crear un archivo de sesión y ubicación como /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If . Para usar N se debe crear todos estos directorios antes de utilizarlo. Para realizar esto, existe un pequeño script tipo shell en ext/session que se llama mod_files.sh, con una versión de Windows llamada mod_files.bat. Observe también que si N se usa y es más grande que 0 no se llevará a cabo la recolección de basura automática, vea una copia de php.ini para más información. También, si usa N, asegúrese de encerrar session.save_path entre "comillas" ya que el separador (;) también se usa para comentarios en php.ini.
AdvertenciaSi se deja esta configuración para un directorio legilble por todo el mundo, tal como /tmp (por defecto), otros usuarios en el servidor pueden ser capaces de secuestrar sesiones obteniendo la lista de archivos de ese directorio.
Nota: Antes de PHP 4.3.6, los usuarios de Windows tenían que cambiar esta variable para usar las funciones de sesiones de PHP. Se debe especificar una ruta válida, p.ej.: c:/temp.
-
session.namestring - session.name specifica el nombre de la sesión que se usa como nombre de cookie. Sólo debería contener caracteres alfanuméricos. Por defecto es PHPSESSID. Véase también session_name().
-
session.auto_startboolean - session.auto_start especifica si el módulo de sesión inicia una sesión automáticamente cuando arranque una petición. Por defecto es 0 (deshabilitado).
-
session.serialize_handlerstring - session.serialize_handler define el nombre del gestor que se usa para serializar/deserializar información. Actualmente, un formato interno de PHP (nombre php o php_binary) y WDDX están soportados (nombre wddx). WDDX sólo está disponible si PHP es compilado con soporte para WDDX. Por defecto es php.
-
session.gc_probabilityinteger - session.gc_probability se usa junto con session.gc_divisor para manejar la probabilidad de que la rutina de gc (garbage collection, recolección de basura) está iniciada. Por defecto es 1. Véase session.gc_divisor para más detalles.
-
session.gc_divisorinteger - session.gc_divisor junto con session.gc_probability define la probabilidad de que el proceso de gc (garbage collection, recolección de basura) esté iniciado en cada inicialización de sesión. La probabilidad se calcula usando gc_probability/gc_divisor, p.ej. 1/100 significa que hay un 1% de probabilidad de que el proceso de GC se inicie en cada petición. session.gc_divisor por defecto es 100.
-
session.gc_maxlifetimeinteger -
session.gc_maxlifetime especifica el número
de segudos transcurridos después de que la información sea vista como 'basura' y
potencialmente limpiada. La recolección de basura puede suceder durante el inicio de sesiones
(dependiendo de session.gc_probability y
session.gc_divisor).
Nota:
Si diferentes scripts tienen diferentes valores de session.gc_maxlifetime pero comparten la misma ubicación para almacenar la información de sesión, la información del script con el mínimo valor será limpiada. En este caso use esta directiva junto con session.save_path.
Nota: Si está usando el gestor de sesiones basado en archivos predeterminado, su sistema de archivos debe llevar la cuenta de los tiempos de acceso (atime). FAT de Windows no lo hace, por lo que tendrá que utilizar otro método para manejar la recolección de basura de su sesión si está utilizando un sistema de archivos FAT o cualquier otro sistema de archivos donde la cuenta de atime no esté disponible. Desde PHP 4.2.3 se ha usado mtime (fecha de modificación) en vez de atime. Por lo tanto, no tendrá problemas con sistemas de archivos donde la cuenta de atime no esté disponible.
-
session.referer_checkstring - session.referer_check contiene la subcadena para comprobar cada HTTP Referer. Si la Referencia fue enviada por el cliente y la subcadena no se encontró, el id de sesión embebido será marcado como no válido. Por defecto es una cadena vacía.
-
session.entropy_filestring -
session.entropy_file da una ruta a un
recurso externo (archivo) que será usado como una fuente de entropía
adicional en el proceso de creación del id de sesión. Ejemplos:
/dev/random o /dev/urandom
que están disponibles en la mayoría de sistemas Unix.
Esta función está disponible en Windows desde PHP 5.3.3. Si se establece
session.entropy_length a un valor que no sea cero
hará que PHP use la Windows Random API como fuente entrópica.
Nota: A partir de PHP 5.4.0 session.entropy_file usa de forma predeterminada /dev/urandom o /dev/arandom si están disponibles. En PHP 5.3.0, esta directiva se deja vacía por omisión.
-
session.entropy_lengthinteger - session.entropy_length especifica el número de bytes que serán leídos desde el archivo especificado arriba. Por defecto es 0 (deshabilitado).
- session.use_cookies especifica si el módulo usará cookies para almacenar el id de sesión en la parte del cliente. Por defecto es 1 (habilitado).
- session.use_only_cookies especifica si el módulo sólo usará cookies para almacenar el id de sesión en la parte del cliente. Habilitar este ajuste previene ataques que impican pasar el id de sesión en la URL. Este ajuste fue añadido en PHP 4.3.0. Por defecto es 1 (habilitado) desde PHP 5.3.0.
-
session.cookie_lifetime especifica el tiempo de vida en
segundos de la cookie que es enviada al navegador. El valor 0
significa "hasta que el navegador se cierre". Por defecto es
0. Véase también
session_get_cookie_params() y
session_set_cookie_params().
Nota:
La marca de tiempo de caducidad se establece relativa a la hora del servidor, la cúal no es necesariamente la misma que la hora del navegador del cliente.
- session.cookie_path especifica la ruta a establecer en la cookie de sesión. Por defecto es /. Véase también session_get_cookie_params() y session_set_cookie_params().
- session.cookie_domain especifica el dominio a establecer en la cookie de sesión. Por defecto es ninguno, significando el nombre de host del servidor que generó la cookie según la especificación de cookies. Véase también session_get_cookie_params() y session_set_cookie_params().
- session.cookie_secure especifica si las cookies deberían enviarse sólo sobre conexiones seguras. Por defecto es off. Este ajuste fue añadido en PHP 4.0.4. Véase también session_get_cookie_params() y session_set_cookie_params().
- Marca la cookie como accesible sólo a través del protocolo HTTP. Esto siginifica que la cookie no será accesible por lenguajes de script, tales como JavaScript. Este ajuste puede ayudar de manera efectiva a reducir robos de indentidad a través de ataques (aunque no está soportado por todos los navegadores).
-
session.cache_limiterstring - session.cache_limiter especifica el método de control de caché usado por páginas de sesión. Puede ser uno de los siguientes valores: nocache, private, private_no_expire, o public. Por defecto es nocache. Vea también la documentación de session_cache_limiter() para informarse sobre lo que significan estos valores.
-
session.cache_expireinteger - session.cache_expire especifica el tiempo de vida en minutos para las páginas de sesión examinadas, esto no tiene efecto para el limitador nocache. Por defecto es 180. Véase también session_cache_expire().
-
session.use_trans_sidboolean -
session.use_trans_sid si está habilitado sid
transparente o no. Por defecto es
0 (deshabilitado).
Nota: Para PHP 4.1.2 o anterior, está habilitado compilando PHP con --enable-trans-sid. Desde PHP 4.2.0, la característica trans-sid es siempre compilada. La administración de sesiones basadas en URL tienen riesgos de seguridad adicionales comparada con la administración de sesiones basdas en cookies. Los usuarios pueden enviar una URL que contenga un ID de sesión activo a sus amigos mediante email o los usuarios pueden guardar una URL que contenga una ID de sesión en sus marcadores y acceder a su sitio siempre con el mismo ID de sesión, por ejemplo.
-
session.bug_compat_42boolean - Las versiones de PHP 4.2.3 y anteriores tienen una característica/error no documentada que permite inicializar una variable de sesión en el ámbito global, aunque register_globals esté deshabilitado. PHP 4.3.0 y posteriores le avisarán, si se usa esta característica, y si session.bug_compat_warn también está habilitado. Esta característica/error puede ser desactivada deshabilitando esta directiva.
-
session.bug_compat_warnboolean - Las versiones de PHP 4.2.3 y anteriores tienen una característica/error no documentada que permite inicializar una variable de sesión en el ámbito global, aunque register_globals esté deshabilitado. PHP 4.3.0 y posteriores le avisarán, si se usa esta característica habilitando session.bug_compat_42 y session.bug_compat_warn.
-
session.hash_functionmixed -
session.hash_function permite especificar el algoritmo
hash utilizado para generar los ID de sesión. '0' significa MD5 (128 bits) y
'1' significa SHA-1 (160 bits).
Desde PHP 5.3.0 también es posible especificar cualquier algoritmo porporcionado por la extensión hash (si está disponible), como sha512 o whirlpool. Una lista completa de los algoritmos soportados se puede obtener con la función hash_algos().
Nota:
Este ajuste fue introducido en PHP 5.
-
session.hash_bits_per_characterinteger -
session.hash_bits_per_character permite definir
cuántos bits son almacenados en cada carácter cuando se convierte la información
hash binaria a algo legible. Los valores posibles son '4' (0-9, a-f),
'5' (0-9, a-v), y '6' (0-9, a-z, A-Z, "-", ",").
Nota:
Esto fue introducido en PHP 5.
-
url_rewriter.tags especifica qué etiquetas HTML
son reescritas para incluir el id de sesión si el soporte para sid transparente
está habilitado. Por defecto es
a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=
Nota: Si quiere compatibilidad para HTML/XHTML estricto, elimine la entrada form y use las etiquetas <fieldset> alrededor de sus campos de formulario.
-
session.upload_progress.enabledboolean - Habilita el seguimiento del progreso de subida de ficheros, rellenado la variable $_SESSION. Por omisión su valor es 1, habilitado.
-
session.upload_progress.cleanupboolean -
Limpieza de la información del progreso al finalizar la lectura de los datos del POST
(p.ej. al finalizar la subida). Por omisión su valor es 1, habilitado.
Nota: Es muy recomendado mantener esta opción habilitada.
-
session.upload_progress.prefixstring - Prefijo usado para la clave del progreso de subida en $_SESSION. Esta clave será concatenada con el valor de $_POST[ini_get("session.upload_progress.name")] para proporcionar un índice único. Por omisión su valor es "upload_progress_".
-
session.upload_progress.namestring - El nombre de la clave a usar en $_SESSION para guardar la información del progreso de subida. Ver también session.upload_progress.prefix. Si no se pasa $_POST[ini_get("session.upload_progress.name")] o no está disponible, el progreso de subida no será grabado. Por omisión su valor es"PHP_SESSION_UPLOAD_PROGRESS".
-
session.upload_progress.freqmixed - Determina cada cuanto debería actualizarse la información del proceso de subida. Este valor puede ser definido en bytes (p.ej. "actualiza la información del progreso de subida después de cada 100 bytes"), o en porcentajes (p.ej. "actualiza la información del proceso de subida después de recibir el 1% del total del tamaño del fichero"). Por omisión "1%".
-
session.upload_progress.min-freqinteger - El retraso mínimo entre actualizaciones, en segundos. Por omisión su valor es "1" (un segundo).
Los ajustes de configuración track_vars y register_globals influyen en cómo las variables de sesión se almacenan y se restablecen.
El progreso de subida no será registrado a no ser que session.upload_progress.enabled esté habilitado, y la variable $_POST[ini_get("session.upload_progress.name")] esté definida. Ver Session Upload Progress para más información de como funciona.
Nota:
A partir de PHP 4.0.3, track_vars está siempre activado.
max value for "session.gc_maxlifetime" is 65535. values bigger than this may cause php session stops working.
apparently the default value for session.use_only_cookies has changed in 5.3.3 from 0 to 1. If you haven't set this in your php.ini or your code to 0 transparent sessions won't work.
Being unable to find an actual copy of mod_files.sh, and seeing lots of complaints/bug fix requests for it, here's one that works. It gets all its parameters from PHP.INI, so you don't have the opportunity to mess up:
#!/bin/bash
#
# Creates directories for PHP session storage.
# Replaces the one that "comes with" PHP, which (a) doesn't always come with it
# and (b) doesn't work so great.
#
# This version takes no parameters, and uses the values in PHP.INI (if it
# can find it).
#
# Works in OS-X and CentOS (and probably all other) Linux.
#
# Feb '13 by Jeff Levene.
[[ $# -gt 0 ]] && echo "$0 requires NO command-line parameters.
It gets does whatever is called for in the PHP.INI file (if it can find it).
" && exit 1
# Find the PHP.INI file, if possible:
phpIni=/usr/local/lib/php.ini # Default PHP.INI location
[[ ! -f "$phpIni" ]] && phpIni=/etc/php.ini # Secondary location
[[ ! -f "$phpIni" ]] && phpIni= # Found it?
# Outputs the given (as $1) parameter from the PHP.INI file:
# The "empty" brackets have a SPACE and a TAB in them.
#
PhpConfigParam() {
[[ ! "$phpIni" ]] && return
# Get the line from the INI file:
varLine=`grep "^[ ]*$1[ ]*=" "$phpIni"`
# Extract the value:
value=`expr "$varLine" : ".*$1[ ]*=[ ]*['\"]*\([^'\"]*\)"`
echo "$value"
}
if [[ "$phpIni" ]]
then
savePath=`PhpConfigParam session.save_path`
# If there's a number and semicolon at the front, remove them:
dirDepth=`expr "$savePath" : '\([0-9]*\)'`
[[ "$dirDepth" ]] && savePath=`expr "$savePath" : '[0-9]*;\(.*\)'` || dirDepth=0
bits=`PhpConfigParam session.hash_bits_per_character`
case "x$bits" in
x) echo "hash_bits_per_character not defined. Not running." ; exit 2 ;;
x4) alphabet='0 1 2 3 4 5 6 7 8 9 a b c d e f' ;;
x5) alphabet='0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v' ;;
x6) alphabet='0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v'
alphabet="$alphabet w x y z A B C D E F G H I J K L M N O P Q R S T U V W"
alphabet="$alphabet X Y Z - ,"
;;
*) echo "unrecognized hash_bits_per_character. Not running." ; exit 2 ;;
esac
else
echo "Cannot find the PHP.INI file. Not running. Sorry."
exit 2
fi
# The depth of directories to create is $1. 0 means just create the named
# directory. Directory to start with is $2.
#
# Used recursively, so variables must be "local".
doDir() {
local dir="$2"
if [[ -d "$dir" ]]
then
echo "Directory '$dir' already exists. No problem."
elif [[ -f "$dir" ]]
then
echo "FILE '$dir' exists. Aborting." ; exit 2
else
if mkdir "$dir"
then
echo "Directory '$dir' created."
else
echo "Cannot create directory '$dir'. Aborting." ; exit 2
fi
fi
chmod a+rwx "$dir"
if [[ $1 -gt 0 ]]
then
local depth=$(( $1 - 1 ))
for letter in $alphabet
do doDir $depth "$dir/$letter"
done
fi
}
echo "Running with savePath='$savePath', dirDepth=$dirDepth, and bitsPerCharacter=$bits."
sleep 3
doDir $dirDepth "$savePath"
exit 0
This is how I set my session.save_path
session.save_path = "1;/home/askapache/tmp/s"
So to create the folder structure you can use this compatible shell script, if you want to create with 777 permissions change the umask to 0000;
sh -o braceexpand -c "umask 0077;mkdir -p s/{0..9}/{a..z} s/{a..z}/{0..9}"
Then you can create a cronjob to clean the session folder by adding this to your crontab which deletes any session files older than an hour:
@daily find /home/askapache/tmp/s -type f -mmin +60 -exec rm -f {} \; &>/dev/null
That will create sessions in folder like:
/home/askapache/tmp/s/b/sess_b1aba5q6io4lv01bpc6t52h0ift227j6
I don't think any non-mega site will need to go more than 1 levels deep. Otherwise you create so many directories that it slows the performance gained by this.
When setting the session.cookie_lifetime directive in a .htaccess use string format like;
php_value session.cookie_lifetime "123456"
and not
php_value session.cookie_lifetime 123456
Using a integer as stated above dit not work in my case (Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.5 with Suhosin-Patch mod_ssl/2.2.11 OpenSSL/0.9.8g)
Recently, I needed to change the session save_path in my program under Windows. With an ini_set('session.save_path', '../data/sessions'); (and session.gc_divisor = 1 for test), I always obtain 'Error #8 session_start(): ps_files_cleanup_dir: opendir(../data/sessions) failed: Result too large'.
I corrected this by changing with ini_set('session.save_path', realpath('../data/sessions'));
session.auto_start should always be "Off".
session.auto_start=On is considered "wrong" by Zend_Session as it causes an E_NOTICE to be thrown when Zend_Session::start() is called (either directly or indirectly, e.g., through Zend_Session_Namespace).
In response to 00 at f00n, this very page explains:
"(...) if N is used and greater than 0 then automatic garbage collection will not be performed (...)"
So you can actually use custom save_path with automatic garbage collection, since you don't use the subdirectory option (that N subdirectory levels).
To get session IDs to show up in URIs, and not get stored via cookies, you must not only set session.use_cookies to 0, but also set session.use_trans_sid to 1. Otherwise, the session ID goes neither in a cookie nor in URIs!
Transient sessions do not appear to be working in 5.3.3
E.g.
<?php
ini_set("session.use_cookies", 0);
ini_set("session.use_trans_sid", 1);
session_start();
if (isset($_SESSION["foo"])) {
echo "Foo: " . $_SESSION["foo"];
} else {
$_SESSION["foo"] = "Bar";
echo "<a href=?" . session_name() . "=" . session_id() . ">Begin test</a>";
}
?>
This works in 5.2.5, but not 5.3.3
