Php не удаляет файлы сессий
3 ответа 3
На момент выполнения session_destroy у вас сессия не активна и соответственно генерируется WARNING. Перед вызовом session_destroy необходимо добавить вызов session_start .
Если у вас после session_destroy сразу идет редирект то удалять данные из глобальной переменной $_SESSION не обязательно, данные в ней будут доступны только на текущем запросе.
сделала так, как вы..получилось вот что Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at Z:\home\registr\www\test\exit.php:1) in Z:\home\registr\www\test\exit.php on line 2
Только не забываем exit; после header: location :) Иначе пойдет дальнейшее выполнение скрипта и редирект произойдет после полной отработки. При удалении $_SESSION['name'] еще и ошибки будут.
Хедер срабатывает потому что скрипт уже отдал тексты ошибок. Хедеры действуют только до отдачи какого-либо текста клиенту, поэтому после выброса ошибок хэдеры не отправляются (это ваше второе предупреждение). А по первому - просто используйте сначала session_destroy() , а потом как угодно сбивайте $_SESSION :)
то есть session_destroy(); unset($_SESSION[name]); header('Location: index.php'); просто местами поменять? но тоже самое получилось(
удаление сессии и по всей видимости у вас перед
имеется какой-то вывод пользователю. echo ?
session_start(); запускается при авторизации пользователя, на index.php возвращаемся на главую стрнацу.. только я так и не поняла в чем ошибка..
session_start(); вызывается не только при авторизации пользователя. она должна вызываться чуть ли не самой первой при каждой загрузке страницы для всех пользователей как авторизованных так и нет. и видимо вам будет много проще сделать loguot на аяксах: выйтиа> или без аякса вовсе: выйтиа> а в loguot.php: session_start(); session_destroy(); $_SESSION=array(); // unset($_SESSIONPhp не удаляет файлы сессий); etc.. header('location: /index.php');
на моем сайте я использую PHP сессии. Информация о сеансе хранится в файлах в my ./ путь к сеансу. Через несколько месяцев я обнаружил, что эти файлы сессий не удаляются, сейчас есть 145.000 их в этот каталог.
как они должны быть очищены? Должен ли я делать это программно, или это параметр, который я могу использовать где-то, чтобы эта очистка происходила автоматически?
- сессии.gc_probability
- сессии.gc_divisor
- сессии.gc_maxlifetime
Debian /Ubuntu обрабатывает это с помощью cronjob, определенного в/etc / cron.d / php5
скрипт maxlifetime просто возвращает количество минут, которое сеанс должен поддерживать, проверяя php.ini, это выглядит так
в случае если кто-то хочет сделать это с cronjob, пожалуйста, имейте в виду, что это:
очень медленно, когда у вас много файлов.
рассмотрите возможность использования этого вместо:
если у вас есть пробелы в именах файлов, используйте это:
xargs заполнит командную строку с файлами, которые будут удалены, а затем запустите rm команда намного меньше, чем -exec rm <> \; , который будет вызывать для каждого файл.
просто мои два цента
используйте cron с find для удаления файлов старше заданного порога. Например, чтобы удалить файлы, которые не были доступны в течение по крайней мере недели.
вы можете создать скрипт / etc / cron.ежечасно / php и ставлю туда:
затем сделайте скрипт исполняемым (chmod +x).
теперь каждый час будут удаляться все файлы сеанса с данными, измененными более 24 минут назад.
Срыв: Только файлы:найти /var / lib/ php5 / - type f
Старше минуты: - cmin
Получить настройки php:$(echo "`php-I|grep-i сессия.gc_maxlifetime
Сделайте математику: / cut-d ''- f3 '/ 60" / bc)
РМ соответствующие файлы: - exec rm-f <> \;
Я думаю, что вы находитесь на общем сервере, и файлы сеанса смешиваются со всеми пользователями, поэтому вы не можете и не должны их удалять. То, что вы можете сделать, если вы беспокоитесь о масштабировании и/или конфиденциальности сеанса ваших пользователей, - это переместить сеансы в базу данных.
начните писать этот файл Cookie в базу данных, и у вас есть долгий путь к масштабированию вашего приложения на нескольких серверах, когда придет время.
кроме того, я бы не стал сильно беспокоиться 145.000 файлов.
cd в каталог сеансов, а затем:
1) просмотр сеансов старше 40 мин: find . -amin +40 -exec stat -c "%n %y" <> \;
2) удалить сеансы старше 40 мин: find . -amin +40 -exec rm <> \;
session_destroy() уничтожает все данные, связанные с текущей сессией. Данная функция не удаляет какие-либо глобальные переменные, связанные с сессией и не удаляет сессионные cookie. Чтобы вновь использовать переменные сессии, следует вызвать session_start() .
Замечание: Нет необходимости вызывать session_destroy() в обычном коде. Очищайте массив $_SESSION вместо удаления данных сессии.
Чтобы полностью удалить сессию, также необходимо удалить и её идентификатор. Если для передачи идентификатора сессии используются cookie (поведение по умолчанию), то сессионные cookie также должны быть удалены. Для этого можно использовать setcookie() .
Немедленное удаление сессии может привести к нежелательным последствиям. При наличии конкурирующих запросов, другие соединения могут столкнуться с внезапной потерей данных сессии, например, это могут быть запросы от JavaScript и/или запросы из ссылок URL.
Даже если текущий модуль сессии не поддерживает пустые cookie идентификатора сессии, немедленное удаление сессии может привести к пустым cookie идентификатора сессии из-за состояния гонки на стороне клиента (браузера). Это приведёт к тому, что клиент создаст множество идентификаторов сессии без необходимости.
Чтобы этого избежать, необходимо установить в $_SESSION временную метку удаления и убрать доступ позже. Или удостовериться, что ваше приложение не имеет конкурирующих запросов. Это также относится к session_regenerate_id() .
Примечания
Замечание:
Используйте session_unset() только для устаревшего кода, где не используется $_SESSION .
Список параметров
У этой функции нет параметров.
Список изменений
Версия | Описание |
---|---|
7.2.0 | Теперь возвращаемый тип этой функции bool . Раньше был тип void . |
User Contributed Notes 8 notes
I was having a problem clearing all session variables, deleting the session, and creating a new session without leaving old session stuff behind in all browsers. The below code is perfect for a logout script to totally delete everything and start new. It even works in Chrome which seems to not work as other browsers when trying do logout and start a new session.
session_start ();
session_unset ();
session_destroy ();
session_write_close ();
setcookie ( session_name (), '' , 0 , '/' );
session_regenerate_id ( true );
?>
The difference between both session_unset and session_destroy is as follows:
session_unset just clears out the session for usage. The session is still on the users computer. Note that by using session_unset, the variable still exists. session_unset just remove all session variables. it does not destroy the session. so the session would still be active.
Using session_unset in tandem with session_destroy however, is a much more effective means of actually clearing out data. As stated in the example above, this works very well, cross browser. session_destroy is destroy the session. session_destroy() to kill all session information. This is the more secure function to use.
To further clarify the note above. this can be done via the session handling directives in your php.ini file. there are options to set garbage collection probability (via percent. i.e. 75 means it would run 3 out of every 4 page accesses), and the amount of time a session object can remain active before the garbage collection process sees it as garbage.
note to Jason: I don't know the exact mechanics of it (since I'm quite new to sessions) but I think you need to use session_unset() BEFORE you can use session_destroy() at all. I thought that session_unset() was for scripted variables, and session_destroy() just for anything saved on your side regarding the session.
There is nothing magical about the $_SESSION superglobal and unsetting it.
One has simply to remember that all the session_* functions will use continue to
use exactly that instance of array that was set up by session_start.
Consider this example:
session_start ();
var_dump ( $_SESSION );
$a =& $_SESSION ;
unset( $_SESSION );
$a [ 'x' ] = 1 ; // $a refers to the original $_SESSION
$_SESSION [ 'x' ] = 2 ; // new unrelated array
session_write_close ();
// saved session contains x => 1
?>
-------------------------------------------------------
InterNic
20-May-2006 11:20
sometimes you might have problems even if using both session_unset and session_destroy. You have to clear the $_SESSION array. I got it working this way:
When I used this method the session still existed in structure until the array is reset completely.
This, however, has the drawback of clearing all sessions which may not be ideal in some cases.
Named sessions may help in such cases.
The difference between both session_unset and session_destroy is as follows:
session_unset just clears out the sesison for usage. The session is still on the users computer. Note that by using session_unset, the variable still exists.
Using session_unset in tandem with session_destroy however, is a much more effective means of actually clearing out data. As stated in the example above, this works very well, cross browser:
I noticed that in firefox, one could simply use sesison_unset and the session would be cleared. When trying this on IE, I was horrified to find out that the data was still there, so I had to use session destroy.
While CLI session_unset() doesn't work (it doesn't clear session variables).
Using CLI you must use:
Частая проблема — tmp папка web сервера вдруг содержит n миллионов файлов. Скорее всего это файлы сессий. И образовались они там не вдруг, а за пару месяцев/лет.
Диагностируем
Во первых, затруднительно посмотреть, что находится в папке, т.к. ни FAR, ни виндовый проводник (серверы с проблемой были на windows) не хотят такую папку открывать (FAR вылетал забрав 1гб оперативной памяти, где-то на чтении трехмиллионного файла). Как зайти в папку, содержащую много файлов? Переходим в папку в консоле через cd (переходит махом не зависимо от количества файлов) и пишем:
dir /p
Это постраничный вывод содержимого каталога. Несколько раз жмем пробел, убеждаясь что все забито файлами сессий.
Исправляем
Что же произошло и почему garbage collector (далее GC) PHP забил на вашу tmp папку и сто лет ее не чистил?
1) Возможно, не правильно заданы параметры php.ini session.gc_probability и session.gc_divisor. Вероятность запуска GC при каждом запуске скрипта - session.gc_probability / session.gc_divisor. По умолчанию — 1/100. Соответственно, если задать session.gc_probability = 0 GC не запустится никогда. Соответсвующие параметры нужно проверить и в коде приложения.
2) Возможно, вы изменили session.save_path в своем приложении, и теперь она отличается от той, которая в php.ini. В этом случае GC чистить в вашей кастомной папке ничего не будет и вам нужно заботиться об этом самим, т.к. он чистит только папку, которая указана в 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
Удаляем
В tmp папке на момент решения проблемы было 4 миллиона файлов. Удалил их просто:
del sess_*
Процесс удаления не слишком нагружает сервер, и было решено просто запустить операцию на сутки. Тихо мирно все старые файлы сессий были выкошены. Обязательно перед удалением меняйте tmp папку сессий, т.к. иначе пользователи вашего ресурса будут все сутки без конца разлогиниваться (в лучщем случае), а в худшем будут толстые дата лосы из-за вашей невнимательности. Сначала смените путь в php.ini, потом удаляйте.
Warning: session_destroy() [function.session-destroy]: Trying to destroy uninitialized session in Z:\home\registr\www\test\exit.php on line 3
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\registr\www\test\exit.php:1) in Z:\home\registr\www\test\exit.php on line 4
Примеры
// Инициализируем сессию.
// Если вы используете session_name("something"), не забудьте добавить это перед session_start()!
session_start ();
// Удаляем все переменные сессии.
$_SESSION = array();
// Наконец, уничтожаем сессию.
session_destroy ();
?>
Примечания
Замечание:
При использовании $_SESSION для удаления переменных сессии, то используйте функцию unset() . Например, unset ($_SESSION['varname']); .
НЕ удаляйте весь массив $_SESSION с помощью unset($_SESSION) , так как это приведёт к невозможности регистрации новых переменных через суперглобальный массив $_SESSION
Замечание:
Используйте session_unset() только для старого кода, который не использует $_SESSION .
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Читайте также: