- Php session start не работает
- PHP: 12 причин, по которым не работают сессии
- Семь причин почему не сохраняется сессия в PHP
- Почему не сохраняется сессия при переходе на другую страницу?
- 1. Вы забыли запустить сессию
- 2. Сессия уничтожается в коде
- 3. Хранилище сессии недоступно для записи
- 4. После отправки заголовка не используется exit();
- 5. Cookies не включены в браузере
- 6. Редирект с одного домена на другой
- 7. У вас нет favicon.ico
- PHP: Самые распространенные проблемы при работе с сессиями
- Записная книжка рассеянного [в пространстве и времени] программиста
- PHP: Самые распространенные проблемы при работе с сессиями
- session_start(): open(filename, O_RDWR) failed: No such file or directory
- session_start(): Session data file is not created by your uid
- session_start(): open(filename, O_RDWR) failed: Permission denied
- Обнаружена активная PHP сессия с вызовом функции session_start() сайта WP: Решение проблемы
- Пошаговые действия по исправлению функции session_start() на session_write_close() в WordPress
- Вывод
- session_start
- Описание
- Список параметров
- Возвращаемые значения
- Список изменений
- Примеры
- Простой пример сессии
- Передача опций в session_start()
- Примечания
- Смотрите также
- User Contributed Notes 38 notes
Php session start не работает
БлогNot. PHP: 12 причин, по которым не работают сессии
PHP: 12 причин, по которым не работают сессии
Хотя PHP последних версий стал работать с сессиями гораздо лучше, начинающие (а порой и опытные) программисты всё ещё нередко мучаются с ними, особенно если речь идёт об адаптации старого кода к новым версиям. В этой заметке я собрал самые распространённые причины, по которым могут не работать сессии (авторизация не выполняется, вход на сайт происходит только со второго раза и т.п.)
Сначала разумные причины:
1. Сессия не запущена.
То есть, не вызывалась функция session_start. Самая банальная и самая частая причина. Вызов session_start должен выполняться на каждой странице, где используются данные из массива $_SESSION .
Лучше всего вызывать session_start сразу после открывающего тега
Я часто в запутанном коде из множества модулей делаю это в виде
Есть смысл также запускать сессию только из модуля с функциями, подключаемыми к каждой странице сайта кодом вроде этого:
2. Сессия или её данные удаляются из кода раньше, чем должны использоваться.
В сложных многомодульных скриптах это вполне возможно, тем более, сделать это можно несколькими способами — через функцию session_destroy, «прямой» очисткой массива сессии кодом вида $_SESSION = array(); или $_SESSION = []; или unset($_SESSION[‘name’]) или просто unset($_SESSION); — в последнем случае, правда, сгенерируется предупреждение. «Прошерстите» код, чтобы убедиться, что этого не происходит.
3. Хранилище сессии недоступно для записи.
Выполните на хосте функцию phpinfo и проверьте значение session.save_path — это папка, куда сохраняется сессия.
Зайдите в неё и посмотрите, есть ли там свежие файлы с именами вроде sess_***** или *****.tmp . Если файлов нет — сессия не может сохраниться из-за отстутствия прав на доступ к папке. Установите их.
4. Данные сессии не записываются после отправки заголовка.
Если страница после выполнения кода редиректит на другую страницу при помощи функции header, может понадобиться добавить непосредственно после вызова header вызов функции session_write_close (или exit , die ), чтобы сессия могла корректно записать данные.
5. В браузере не включены Cookies.
Механизм куки-файлов необходим для работы сессий. Проверьте, что куки разрешены в браузере.
6. В коде или настройках сайта происходит редирект с одного домена на другой.
При редиректе сессия потеряется, даже если это редирект с site.com на www.site.com или наоборот.
7. Некорректная работа со временем в скрипте.
Скрипт имеет тысячу и один способ использовать время, отличающееся от серверного, в том числе, ставить время для куки и т.п.
А что если в момент создания кука оказывается уже просроченной?
Неплохо также в файле .htaccess настроить часовой пояс явно, скажем
8. Устаревшие функции сессий.
Например, код всё ещё использует session_register, а она давно удалена из языка. Проверьте и другие функции сессий — нужно ли их все применять?
Мне сегодня помог п. 4 при «реанимации» работающего «со второго входа» сайтега.
Теперь причины более экзотические, которых, вроде бы, не должно быть, а они случаются.
9. На сайте нет файла favicon.ico или favicon.png
Некоторым бразуерам (Chrome) на некоторых серверах (nginx) это может помешать работе с сессиями, хотя понятных причин я назвать не могу.
10. У вас в файле кодировка UTF-8 с меткой BOM.
Избавьтесь от неё. Хотя, по идее, вы должны были увидеть раньше популярнейшее предупреждение (warning) «headers already sent» (см. по ссылке). Но бывает, что не усмотрел директивы отключения варнингов где-нибудь в недрах кода. Кстати, включите контроль всех ошибок при работе.
11. Лишние символы, например, пробелы после закрывающего тега PHP ?>
Что тут сказать? Избавьтесь от них.
12. Так легла карта.
Скорее всего, сессия просто стартует не там, где Вы думаете.
Источник
Семь причин почему не сохраняется сессия в PHP
Когда вебмастер начинает работать с сессиями, он часто сталкивается с тем, что сессия не сохраняется при переходе на другую страницу. Причин может быть множество, ниже представлен список наиболее распространённых, изучив которые, вы сможете решить проблему.
Почему не сохраняется сессия при переходе на другую страницу?
1. Вы забыли запустить сессию
Пожалуй, это самая распространённая причина почему не сохраняется сессия. Запуск сессии посредством функции session_start(); должен осуществляться на каждой странице, где используется сессия. Лучше всего session_start(); писать сразу после открывающего тега
2. Сессия уничтожается в коде
Прежде чем пропускать этот пункт и идти далее с мыслью «Да ну, бред какой-то, нигде я сессию не уничтожаю.», удостоверьтесь, действительно ли вы нигде не очищаете сессию? Уничтожить сессию можно с помощью функции session_destroy(); или вы можете очистить значения сессии путём следующей конструкции: unset($_SESSION[‘name’]); . Убедитесь, что у вас этого нет.
3. Хранилище сессии недоступно для записи
Для начала проверьте куда у вас записывается сессия. Выполните phpinfo(); и посмотрите значение параметра session.save_path . Это и есть директория, куда сохраняется сессия. Зайдите в неё и посмотрите, есть ли там файлы типа «0Thee5g9vsknDhen14kyYt5lv7» . Если файлов нет, значит сессия не может сохраниться, посмотрите правильно ли выставлены права доступа к директории.
4. После отправки заголовка не используется exit();
В случае, если на странице отправляются заголовки при помощи функции header() , необходимо добавить конструкцию exit(); или session_write_close(); , чтобы сессия могла корректно отработать.
5. Cookies не включены в браузере
Убедитесь, что использование cookies разрешено в браузере, в котором используется сайт.
6. Редирект с одного домена на другой
При редиректе с одного домена на другой сессия потеряется. Даже если это один домен и он отличается наличием «www», например при перенаправлении с «site.com» на «www.site.com» сессия пропадёт, убедитесь, что у вас этого не происходит.
7. У вас нет favicon.ico
Пожалуй, самая экзотическая из всех вышеперечисленных причин, почему сессия может не сохранятся. Я не знаю почему так происходит, но если у вас нет favicon’а на сайте, браузер Google Chrome может «потерять» вашу сессию. Это бывает не на всех серверах, подобный глюк я обнаружил на nginx’е.
Здравствуй дорогой читатель! Я рад приветствовать тебя на страницах моего блога. Уже несколько лет я занимаюсь веб-программированием и рад поделиться с тобой своими знаниями и советами. Если тебе понравились мои статьи, ты можешь подписаться на рассылку блога, из неё ты узнаешь много интересного!
полдня сегодня мучился над http://www.bestflora.ru/, оказывается UTF был с сигнатурой сохранен! :)) Так что тоже берите на заметку
Есть ещё одна. Если произошел вывод текста(пробельные символы после закрывающего тэга PHP), до session_start(). сессия также может слететь. Но не всегда. Кто-нибудь может объяснить, почему так происходит
Источник
PHP: Самые распространенные проблемы при работе с сессиями
Записная книжка рассеянного [в пространстве и времени] программиста
PHP: Самые распространенные проблемы при работе с сессиями
Рассмотрим наиболее часто встречающиеся проблемы сессий на файлах (мы не будем затрагивать сессии в бд и кастомные обработчики).
session_start(): open(filename, O_RDWR) failed: No such file or directory
Очевидно, что ошибка возникает, когда не существует пути, по которому пишутся данные. Но при этом вы знаете, что на диске каталог, который был указан как аргумент session_save_path(), существует.
Вы увидите на экране или в логах ошибку из заголовка (не во всех дистрибутивах).
Можно посмотреть audit.log из selinux, но если там нет ничего подозрительного и каталог действительно есть (а вы его создали выше), то причина такого поведения достаточно неожиданна.
Происходит это потому что вы работаете в centos 7 версии (или redhat\fedora) и выше. Именно в этой версии ввели параметр PrivateTmp для сервисов. Что это означает для нас?
Сделайте второй скрипт, который перечисляет содержимое директории /tmp, а так же выводит реальный путь каталога /tmp/sessions.
Откройте скрипт в браузере. Вы увидите, что содержимое в браузере кардинально отличается от содержимого реальной папки /tmp. На скриншоте мы видем вывод из консоли и из браузера — результат совершенно разный.
Как это побороть? Использовать другой каталог для хранения сессий. Или перед стартом приложения проверять и создавать в случае необходимости нужную файловую структуру.
session_start(): Session data file is not created by your uid
Не самая распространенная ошибка. Чаще всего возникает в виртуальных окружениях.
Ошибка возникает в случае, когда uid владельца файла сессии не совпадает с uid текущего пользователя под которым запущен интерпретатор.
Как проверить, что это именно наш случай? Нужно создать скрипт, которыый создает файл в каталоге, в котором вы планируете размещать сессии и сверяет uid владельца файла и uid владельца процесса.
Если мы увидим false, то да. Проблема имеет мысто быть. И вам нужно переместить сессии в другое место.
Так же подобное поведение характерно при некоторых способах монтирования nfs.
session_start(): open(filename, O_RDWR) failed: Permission denied
Каталог недоступен для записи и достаточно дать права 777. Но тут не все так очевидно и данный трюк действует не всегда. Если вы работаете в дистрибутивах, которые используют selinux, то даже при установке полных прав система можем вам не позволить писать по выбранному пути.
Это происходит потому что контекст процесса отличается от контекста папки. Вы всегда можете посмотреть в /var/log/audit/audit.log чтобы убедиться.
Как обращаться с контекстами можно подробнее посмотреть в документации и в книге.
Источник
Обнаружена активная PHP сессия с вызовом функции session_start() сайта WP: Решение проблемы
Приветствую Вас, друзья! Столкнулся с такой проблемой, плагин Yoast SEO выдавал критическую ошибку «Обнаружена активная PHP сессия»:
Сессия PHP была создана вызовом функции session_start(). Это препятствует работе REST API и петлевых запросов. Сессия должна быть закрыта функцией session_write_close() перед выполнением любых HTTP-запросов.
Как-то руки не доходили добраться до этого, ошибка висела, особого внимания не обращал. Решил посмотреть как исправить, заглянул на некоторые сайты и увидел, что такая проблема не только у меня.
Нашёл какие-то рекомендации, заумные посты программистов, но решения не нашёл . Немного повозился, выявил причину и решение как исправить эту беду в моём случае на WordPress.
Пошаговые действия по исправлению функции session_start() на session_write_close() в WordPress
Сначала надо выявить причину, что влияет на появление ошибки, плагины или шаблон. Первым делом проверить установленные контактные формы путём их отключения, возможно на этом ваши поиски закончатся.
В моём случае начал проверять плагины:
- Установил плагин «Health Check & Troubleshooting» для выявления неисправности. Он позволяет перейти в «настроечный режим» и отключать все плагины, тему, но при этом сайт будет работать для посетителей в нормальном режиме;
- Переходите в настроечный режим и смело можно в нём работать, не опасаясь за исправную работу сайта в это время;
- В результате манипуляций определил причину: Контактная форма «Contact Form by BestWebSoft», при его отключении проблема функции session_start() исчезала;
- Установил «Contact Form 7», проверил: Проблемка закрыта.
Критическую ошибку с функцией «session_start()» может показывать не только Yoast, но и другой плагин SEO, например, All in One SEO Pack. Во время проверки откройте окно со страницей критической ошибки, по мере включений-выключений плагинов для надёжности обновляйте, чтобы не пропустить виновника.
Вывод
Конфигурация моего сайта видимо не уживалась с контактной формой «Contact Form by BestWebSoft», возможно у вас будет причина в других установленных или в шаблоне.
Делитесь, какие причины выдавали вам проблему с функцией session_write_close(), удалось ли выявить и исправить проблему. Какими способами?
Источник
session_start
(PHP 4, PHP 5, PHP 7, PHP 8)
session_start — Стартует новую сессию, либо возобновляет существующую
Описание
Функция session_start() создаёт сессию, либо возобновляет существующую, основываясь на идентификаторе сессии, переданном через GET- или POST-запрос, либо переданный через cookie.
Когда вызвана функция session_start() или когда сессия создаётся автоматически, PHP вызовет открытие и чтение обработчиков записи сессии. Это могут быть как встроенные обработчики, так и предоставляемые модулями (например, SQLite или Memcached); или вообще определённый пользователем обработчик, заданный функцией session_set_save_handler() . Callback-функция чтения извлечёт все существующие данные сессии (сохранённые в специальном сериализованном виде), десериализует их и занесёт в суперглобальный массив $_SESSION, после чего вернёт сохранённые данные обработчику сессий PHP.
Для использования именованных сессий, используйте session_name() перед session_start() .
Если разрешена опция session.use_trans_sid, функция session_start() регистрирует внутренний обработчик вывода для перезаписи URL.
Если пользователь использует ob_gzhandler или что-то подобное совместно с функцией ob_start() , порядок функций важен для правильного вывода. К примеру, ob_gzhandler должен быть зарегистрирован до старта сессии.
Список параметров
Если задано, то должно быть ассоциативным массивом, переопределяющим текущие директивы конфигурации сессий. Ключи не должны иметь префикса session. .
В дополнение к обычному набору конфигурационных директив, может быть добавлена опция read_and_close . Если установлена в true , то сессия будет закрыта сразу же после прочтения, теоретически позволяя избежать блокировки, если данные сессии не будут изменяться.
Возвращаемые значения
Функция возвращает true , если сессия успешно стартована, в противном случае false .
Список изменений
| Версия | Описание |
|---|---|
| 7.1.0 | session_start() теперь возвращает false и больше не инициализирует $_SESSION , когда она не смогла запустить сессию. |
Примеры
Простой пример сессии
Пример #1 page1.php
echo ‘Добро пожаловать на страницу 1’ ;
$_SESSION [ ‘favcolor’ ] = ‘green’ ;
$_SESSION [ ‘animal’ ] = ‘cat’ ;
$_SESSION [ ‘time’ ] = time ();
// Работает, если сессионная cookie принята
echo ‘
page 2′ ;
// Или можно передать идентификатор сессии, если нужно
echo ‘
. SID . ‘»>page 2’ ;
?>
После просмотра page1.php , вторая страница page2.php чудесным образом получит все данные сессии. Читайте раздел работа с сессиями, там рассказывается про передачу идентификаторов сессий. В частности там рассказывается про то, что такое константа SID .
Пример #2 page2.php
echo ‘Добро пожаловать на страницу 2
‘ ;
echo $_SESSION [ ‘favcolor’ ]; // green
echo $_SESSION [ ‘animal’ ]; // cat
echo date ( ‘Y m d H:i:s’ , $_SESSION [ ‘time’ ]);
// Можете тут использовать идентификатор сессии, как в page1.php
echo ‘
page 1′ ;
?>
Передача опций в session_start()
Пример #3 Переопределение времени жизни cookie
Пример #4 Чтение и закрытие сессии
Примечания
Для использования сессий на основе cookie, функция session_start() должна быть вызвана перед выводом чего бы то ни было в браузер.
Эта функция отсылает несколько заголовков HTTP, в зависимости от настроек. Смотрите описание функции session_cache_limiter() для управления этими заголовками.
Смотрите также
- $_SESSION
- Директива конфигурации session.auto_start
- session_id() — Получает и/или устанавливает идентификатор текущей сессии
User Contributed Notes 38 notes
If you want to handle sessions with a class, I wrote this little class:
/*
Use the static method getInstance to get the object.
*/
class Session
<
const SESSION_STARTED = TRUE ;
const SESSION_NOT_STARTED = FALSE ;
// The state of the session
private $sessionState = self :: SESSION_NOT_STARTED ;
// THE only instance of the class
private static $instance ;
private function __construct () <>
/**
* Returns THE instance of ‘Session’.
* The session is automatically initialized if it wasn’t.
*
* @return object
**/
public static function getInstance ()
<
if ( !isset( self :: $instance ))
<
self :: $instance = new self ;
>
self :: $instance -> startSession ();
return self :: $instance ;
>
/**
* (Re)starts the session.
*
* @return bool TRUE if the session has been initialized, else FALSE.
**/
public function startSession ()
<
if ( $this -> sessionState == self :: SESSION_NOT_STARTED )
<
$this -> sessionState = session_start ();
>
return $this -> sessionState ;
>
/**
* Stores datas in the session.
* Example: $instance->foo = ‘bar’;
*
* @param name Name of the datas.
* @param value Your datas.
* @return void
**/
public function __set ( $name , $value )
<
$_SESSION [ $name ] = $value ;
>
/**
* Gets datas from the session.
* Example: echo $instance->foo;
*
* @param name Name of the datas to get.
* @return mixed Datas stored in session.
**/
public function __get ( $name )
<
if ( isset( $_SESSION [ $name ]))
<
return $_SESSION [ $name ];
>
>
public function __isset ( $name )
<
return isset( $_SESSION [ $name ]);
>
public function __unset ( $name )
<
unset( $_SESSION [ $name ] );
>
/**
* Destroys the current session.
*
* @return bool TRUE is session has been deleted, else FALSE.
**/
public function destroy ()
<
if ( $this -> sessionState == self :: SESSION_STARTED )
<
$this -> sessionState = ! session_destroy ();
unset( $_SESSION );
return ! $this -> sessionState ;
>
// We get the instance
$data = Session :: getInstance ();
// Let’s store datas in the session
$data -> nickname = ‘Someone’ ;
$data -> age = 18 ;
// Let’s display datas
printf ( ‘
My name is %s and I\’m %d years old.
‘ , $data -> nickname , $data -> age );
/*
It will display:
printf ( » , print_r ( $_SESSION , TRUE ));
// TRUE
var_dump ( isset( $data -> nickname ));
// We destroy the session
$data -> destroy ();
// FALSE
var_dump ( isset( $data -> nickname ));
?>
I prefer using this class instead of using directly the array $_SESSION.
As others have noted, PHP’s session handler is blocking. When one of your scripts calls session_start(), any other script that also calls session_start() with the same session ID will sleep until the first script closes the session.
A common workaround to this is call session_start() and session_write_close() each time you want to update the session.
The problem with this, is that each time you call session_start(), PHP prints a duplicate copy of the session cookie to the HTTP response header. Do this enough times (as you might do in a long-running script), and the response header can get so large that it causes web servers & browsers to crash or reject your response as malformed.
This error has been reported to PHP HQ, but they’ve marked it «Won’t fix» because they say you’re not supposed to open and close the session during a single script like this. https://bugs.php.net/bug.php?id=31455
As a workaround, I’ve written a function that uses headers_list() and header_remove() to clear out the duplicate cookies. It’s interesting to note that even on requests when PHP sends duplicate session cookies, headers_list() still only lists one copy of the session cookie. Nonetheless, calling header_remove() removes all the duplicate copies.
/**
* Every time you call session_start(), PHP adds another
* identical session cookie to the response header. Do this
* enough times, and your response header becomes big enough
* to choke the web server.
*
* This method clears out the duplicate session cookies. You can
* call it after each time you’ve called session_start(), or call it
* just before you send your headers.
*/
function clear_duplicate_cookies () <
// If headers have already been sent, there’s nothing we can do
if ( headers_sent ()) <
return;
>
$cookies = array();
foreach ( headers_list () as $header ) <
// Identify cookie headers
if ( strpos ( $header , ‘Set-Cookie:’ ) === 0 ) <
$cookies [] = $header ;
>
>
// Removes all cookie headers, including duplicates
header_remove ( ‘Set-Cookie’ );
// Restore one copy of each cookie
foreach( array_unique ( $cookies ) as $cookie ) <
header ( $cookie , false );
>
>
?>
The constant SID would always be » (an empty string) if directive session.use_trans_sid in php ini file is set to 0.
So remember to set session.use_trans_sid to 1 and restart your server before you use SID in your php script.
If you are using a custom session handler via session_set_save_handler() then calling session_start() in PHP 7.1 you might see an error like this:
session_start(): Failed to read session data: user (path: /var/lib/php/session) in .
As of this writing, it seems to be happening in PHP 7.1, and things look OK in PHP7.0.
It is also hard to track down because if a session already exists for this id (maybe created by an earlier version of PHP), it will not trigger this issue because the $session_data will not be null.
The fix is simple. you just need to check for ‘null’ during your read function:
function read ( $id )
<
//. pull the data out of the DB, off the disk, memcache, etc
$session_data = getSessionDataFromSomewhere ( $id );
//check to see if $session_data is null before returning (CRITICAL)
if( is_null ( $session_data ))
<
$session_data = » ; //use empty string instead of null!
>
PHP locks the session file until it is closed. If you have 2 scripts using the same session (i.e. from the same user) then the 2nd script will not finish its call to session_start() until the first script finishes execution.
If you have scripts that run for more than a second and users may be making more than 1 request at a time then it is worth calling session_write_close() as soon as you’ve finished writing session data.
// a lock is places on the session, so other scripts will have to wait
session_start ();
// do all your writing to $_SESSION
$_SESSION [ ‘a’ ] = 1 ;
// $_SESSION can still be read, but writing will not update the session.
// the lock is removed and other scripts can now read the session
session_write_close ();
I recently made an interesting observation:
It seems that `session_start()` can return `true` even if the session was not properly created. In my case, the disk storage was full and so the session data could not be written to disk. I had some logic that resulted in an infinite loop when the session was not written to disk.
To check if the session really was saved to disk I used:
«`
function safe_session_start () <
# Attempt to start a session
if (!@\ session_start ()) return false ;
#
# Check if we need to perform
# the write test.
#
if (!isset( $_SESSION [ ‘__validated’ ])) <
$_SESSION [ ‘__validated’ ] = 1 ;
# Attempt to write session to disk
@\ session_write_close ();
# Unset the variable from memory.
# This step may be unnecessary
unset( $_SESSION [ ‘__validated’ ]);
# Re-start session
@\ session_start ();
# Check if variable value is retained
if (!isset( $_SESSION [ ‘__validated’ ])) <
# Session was not written to disk
return false ;
>
>
if (! safe_session_start ()) <
# Sessions are probably not written to disk.
# Handle error accordingly.
>
Took me quite a while to figure this out.
Maybe it helps someone!
Unfortunately, after pulling my hair out trying to figure out why my application was working fine in every browser other than IE ( Internet Explorer) (Opera, Chrome, Firefox, Safari are what I’ve tested this in) — when using a DNS CNAME record (like a vanity name that is different from the DNS A record, which is the hostname of the server) sessions do not work correctly.
If you store a session var while on the CNAME:
vanity.example.com and the hostname of the server is hosname.example.com
Then try to call the variable from a different page, it will not find it because of the CNAME (I guess it store the variable under the hostname, then when trying to read it it’s still looking under the CNAME) the same application works fine when accessing it under the hostname directly. Keep in mind that I was testing this on an internal network.
PHP Manual specifically denotes this common mistake:
Depending on the session handler, not all characters are allowed within the session id. For example, the file session handler only allows characters in the range a-z A-Z 0-9 , (comma) and — (minus)!
See session_id() manual page for more details.
The following code shows how the PHP session works. The function my_session_start() does almost the same thing as session_start().
( E_ALL );
ini_set ( ‘display_errors’ , true );
ini_set ( ‘session.save_path’ , __DIR__ );
session id: ‘ . my_session_id (). ‘
$now = date ( ‘H:i:s’ );
if (isset( $_SESSION [ ‘last_visit_time’ ])) <
echo ‘
Last Visit Time: ‘ . $_SESSION [ ‘last_visit_time’ ]. ‘
Current Time: ‘ . $now . ‘
$_SESSION [ ‘last_visit_time’ ] = $now ;
function my_session_start () <
global $phpsessid , $sessfile ;
if (!isset( $_COOKIE [ ‘PHPSESSID’ ]) || empty( $_COOKIE [ ‘PHPSESSID’ ])) <
$phpsessid = my_base32_encode ( my_random_bytes ( 16 ));
setcookie ( ‘PHPSESSID’ , $phpsessid , ini_get ( ‘session.cookie_lifetime’ ), ini_get ( ‘session.cookie_path’ ), ini_get ( ‘session.cookie_domain’ ), ini_get ( ‘session.cookie_secure’ ), ini_get ( ‘session.cookie_httponly’ ));
> else <
$phpsessid = substr ( preg_replace ( ‘/[^a-z0-9]/’ , » , $_COOKIE [ ‘PHPSESSID’ ]), 0 , 26 );
>
$sessfile = ini_get ( ‘session.save_path’ ). ‘/sess_’ . $phpsessid ;
if ( is_file ( $sessfile )) <
$_SESSION = unserialize ( file_get_contents ( $sessfile ));
> else <
$_SESSION = array();
>
register_shutdown_function ( ‘my_session_save’ );
>
function my_session_save () <
global $sessfile ;
file_put_contents ( $sessfile , serialize ( $_SESSION ));
>
function my_session_id () <
global $phpsessid ;
return $phpsessid ;
>
function my_random_bytes ( $length ) <
if ( function_exists ( ‘random_bytes’ )) <
return random_bytes ( $length );
>
$randomString = » ;
for ( $i = 0 ; $i $length ; $i ++) <
$randomString .= chr ( rand ( 0 , 255 ));
>
return $randomString ;
>
function my_base32_encode ( $input ) <
$BASE32_ALPHABET = ‘abcdefghijklmnopqrstuvwxyz234567’ ;
$output = » ;
$v = 0 ;
$vbits = 0 ;
for ( $i = 0 , $j = strlen ( $input ); $i $j ; $i ++) <
$v 8 ;
$v += ord ( $input [ $i ]);
$vbits += 8 ;
while ( $vbits >= 5 ) <
$vbits -= 5 ;
$output .= $BASE32_ALPHABET [ $v >> $vbits ];
$v &= (( 1 $vbits ) — 1 );
>
>
if ( $vbits > 0 ) <
$v 5 — $vbits );
$output .= $BASE32_ALPHABET [ $v ];
>
return $output ;
>
When you have an import script that takes long to execute, the browser seem to lock up and you cannot access the website anymore. this is because a request is reading and locking the session file to prevent corruption.
you can either
— use a different session handler with session_set_save_handler()
— use session_write_close() in the import script as soon you don’t need session anymore (best moment is just before the long during part takes place), you can session_start when ever you want and as many times you like if your import script requires session variables changed.
example
(); //initiate / open session
$_SESSION [ ‘count’ ] = 0 ; // store something in the session
session_write_close (); //now close it,
# from here every other script can be run (and makes it seem like multitasking)
for( $i = 0 ; $i 100 ; $i ++) < //do 100 cycles
session_start (); //open the session again for editing a variable
$_SESSION [ ‘count’ ] += 1 ; //change variable
session_write_close (); //now close the session again!
sleep ( 2 ); //every cycle sleep two seconds, or do a heavy task
>
?>
A session created with session_start will only be available to pages within the directory tree of the page that first created it.
i.e. If the page that first creates the session is /dir1/dir2/index.php and the user then goes to any page above dir2 (e.g. /dir1/index.php), session_start will create a new session rather than use the existing one.
3 easy but vital things about Sessions in AJAX Apps.
// It is VERY important to include a Period if using
// a whole domain. (.yourdomain.com)
// It is VERY important to set the root path your session will always
// operate in. (/members) will ensure sessions will NOT be interfered
// with a session with a path of say (/admin) . so you can log in
// as /admin and as /members. NEVER do unset($_SESSION)
// $_SESSION=array(); is preferred, session_unset(); session_destroy();
session_set_cookie_params ( 0 , ‘/members’ , ‘.yourdomain.com’ , 0 , 1 );
session_start ();
$_SESSION = array();
session_unset ();
session_destroy ();
session_set_cookie_params ( 0 , ‘/members’ , ‘.yourdomain.com’ , 0 , 1 );
session_start ();
$_SESSION [ ‘whatever’ ] = ‘youwhat’ ;
// To be safe, clear out your $_SESSION array
// Next, what most people do NOT do is delete the session cookie!
// It is easy to delete a cookie by expiring it long before the current time.
// The ONLY WAY to delete a cookie, is to make sure ALL parameters match the
// cookie to be deleted. which is easy to get those params with
// session_get_cookie_params().
// FInally, use session_unset(); and session_destroy(); in this order to ensure
// Chrome, IE, Firefox and others, are properly destroying the session.
$_SESSION = array();
if ( ini_get ( ‘session.use_cookies’ ))
<
$p = session_get_cookie_params ();
setcookie ( session_name (), » , time () — 31536000 , $p [ ‘path’ ], $p [ ‘domain’ ], $p [ ‘secure’ ], $p [ ‘httponly’ ]);
>
session_unset ();
session_destroy ();
// AJAX and SESSIONS.
// Example. you start a session based PHP page, which then calls an Ajax (XMLHTTP) authenticated
// using the SAME SESSION to Poll and output the data, for example. But, you notice when you
// try to start the Polling AJAX call always HANGS and seems to hang at the session_start().
// This is because the session is opened in the first page, calls the AJAX polling example, and
// tries to open the same session (for authentication) and do the AJAX call, you MUST call
// session_write_close(); meaning you are done writing to the $_SESSION variable, which really
// represents a file that must be CLOSED with session_write_close();.
// THAN you can call your AJAX Polling code to reopen the same session and do its polling.
// Normally, the $_SESSION is closed automatically when the script is closed or finished executing
// So, if you need to keep a PHP page running after opening a SESSION, simply close it when finished
// writing to $_SESSION so the AJAX polling page can authenticate and use the same session in a
// seperate web page.
?>
Hope this helps someone with their sessions.
Thanks.
If you open a popup window (please no commercial ones!) with javascript window.open it might happen IE blocks the session cookie.
A simple fix for that is opening the new window with the session ID in a GET value. Note I don’t use SID for this, because it will not allways be available.
—-page.php—-
//you must have a session active here
window.open(‘popup.php?sid= echo session_id (); ?> ‘, ‘700×500’, ‘toolbar=no, status=no, scrollbars=yes, location=no, menubar=no, directories=no, width=700, height=500’);
—-popup.php—-
( strip_tags ( $_GET [ ‘sid’ ]));
session_start ();
//and go on with your session vars
?>
If you ever need to open multiple distinct sessions in the same script and still let PHP generate session ids for you, here is a simple function I came up with (PHP default session handler is assumed):
/**
* Switch to or transparently create session with name $name.
* It can easily be expanded to manage different sessions lifetime.
*/
function session_switch ( $name = «PHPSESSID» ) <
static $created_sessions = array();
if ( session_id () != » ) < // if a session is currently opened, close it
session_write_close ();
>
session_name ( $name );
if (isset( $_COOKIE [ $name ])) < // if a specific session already exists, merge with $created_sessions
$created_sessions [ $name ] = $_COOKIE [ $name ];
>
if (isset( $created_sessions [ $name ])) < // if existing session, impersonate it
session_id ( $created_sessions [ $name ]);
session_start ();
> else < // create new session
session_start ();
$_SESSION = array(); // empty content before duplicating session file
// duplicate last session file with new id and current $_SESSION content
// If this is the first created session, there is nothing to duplicate from and passing true as argument will take care of «creating» only one session file
session_regenerate_id (empty( $created_sessions ));
$created_sessions [ $name ] = session_id ();
>
>
session_switch ( «SESSION1» );
$_SESSION [ «key» ] = «value1» ; // specific to session 1
session_switch ( «SESSION2» );
$_SESSION [ «key» ] = «value2» ; // specific to session 2
session_switch ( «SESSION1» );
// back to session 1
// .
?>
When using this function, session_start() should not be called on its own anymore (can be replaced with a call to session_switch() without argument).
Also remember that session_start() sets a Set-Cookie HTTP header on each call, so if you echo in-between sessions, wrap with ouput buffering.
Note: it’s probably rarely a good idea to handle multiple sessions so think again if you think you have a good use for it.
Personally it played its role for some quick patching of legacy code I had to maintain.
Be warned that depending on end of script to close the session will effectively serialize concurrent session requests. Concurrent background «data retrieval» (e.g. applications such as AJAX or amfphp/Flex) expecting to retrieve data in parallel can fall into this trap easily.
Holding the session_write_close until after an expensive operation is likewise problematic.
To minimize effects, call session_write_close (aka session_commit) as early as practical (e.g. without introducing race conditions) or otherwise avoid the serialization bottleneck.
Initiating a session may overwrite your own custom cache control header, which may break clicking back to get back to a prior post request (on Chrome at least).
On my system it was setting ‘no-store’, which is much more severe than ‘no-cache’ and what was breaking the back-button.
If you are controlling your own cache headers carefully you need to call:
session_cache_limiter(»);
. to stop it changing your cache control headers.
To avoid the notice commited by PHP since 4.3.3 when you start a session twice, check session_id() first:
if (session_id() == «»)
session_start();
I just need with easy, count how many times the page reload over the site, may to add a warning popup, while the counter is 0:
session_start();
if(isset($_SESSION[‘count’]))<
$count = $_SESSION[‘count’];
$count++;
$count = $_SESSION[‘count’] = $count;
> else <
$count = $_SESSION[‘count’] = 0;
>
echo $count;
A note about session_start(), custom handlers and database foreign key constraints, which I think may be of some use.
We know that if we want our sessions into a database table (rather than the default storage), we can refer to session_set_save_handler(. ) to get them there. Note that session_set_save_handler must (obviously) be called before session_start(), but let me get to the point.
Upon calling session_start() the «first time», when the session does not already exist, php will spawn a new session but will not call the write handler until script execution finishes.
Thus, the session at this point exists in the server process memory, but won’t be visible as a row in the DB before the script ends.
This seems reasonable, because this avoids some unnecessary database access and resource usage before we even populate our session with meaningfull and definitive data, but this also has side-effects.
In my case, the script called session_start() to make sure a session was initiated, then used session_id() to populate another table in the DB, which had foreign_key constraint to the «sessions» table. This failed because no session was in the db at that point, yet!
I know I could simply force the creation of the row in the DB by manually calling the write handler after session_start(), when necessary, but I am not sure if this is the best possible approach.
As soon as I find an «elegant» solution, or a completely different approach, I will post some working sample code.
In the meanwhile. have fun!
A simple session_start() will not be sufficiant to kepp you Session alive.
Due to the filesystems mounting parameters, atime will normally not be updated. Instead of atime, mtime will be delivered.
This behavior may cause an early session death and your users my be kicked of your login system.
To keep the session alive it will be necessary to write something into the sessionfile at each request, e. g. a simple
That would keep your session alive, even if the client in reality is only clicking around the site.
James at skinsupport dot com raises a good point (warning) about additional requests from the browser. The request for favicon.ico, depending on how it is handled, can have unintended results on your sessions.
For example, suppose you have ErrorDocument 404 /signin.php, no favicon.ico file and all pages in your site where the user signs in are also redirected to /signin.php if they’re not already signed in.
If signin.php does any clean up or reassigning of session_id (as all good signin.php pages should) then the additional request from the browser for favicon.ico could potentially corrupt the session as set by the actual request.
Kudos to James for pointing it out and shame on me for skimming past it and not seeing how it applied to my problem. Thanks too to the Firefox Live HTTP Headers extension for showing the additional request.
Don’t waste days or even hours on this if your session cookies are not being sent or if the session data isn’t what you expect it to be. At a minimum, eliminate this case and see if any additional requests could be at fault.
A handy script that checks fot the presence of uft-8 byte order mark (BOM) in all files in all directories starting on current dir. Combined from the work of other people here.
function fopen_utf8 ( $filename ) <
$file = @ fopen ( $filename , «r» );
$bom = fread ( $file , 3 );
if ( $bom != b»\xEF\xBB\xBF» )
<
return false ;
>
else
<
return true ;
>
>
function file_array ( $path , $exclude = «.|..|design» , $recursive = true ) <
$path = rtrim ( $path , «/» ) . «/» ;
$folder_handle = opendir ( $path );
$exclude_array = explode ( «|» , $exclude );
$result = array();
while( false !== ( $filename = readdir ( $folder_handle ))) <
if(! in_array ( strtolower ( $filename ), $exclude_array )) <
if( is_dir ( $path . $filename . «/» )) <
// Need to include full «path» or it’s an infinite loop
if( $recursive ) $result [] = file_array ( $path . $filename . «/» , $exclude , true );
> else <
if ( fopen_utf8 ( $path . $filename ) )
<
//$result[] = $filename;
echo ( $path . $filename . «
» );
>
>
>
>
return $result ;
>
For those of you running in problems with UTF-8 encoded files:
I was getting an error because of the BOM, although i set Dreamweaver to «save as» the without the BOM. It appears that DW will not change this setting in already existing files. After creating a new file withou the BOM, everything worked well.
I also recommend http://people.w3.org/rishida/utils/bomtester/index.php — a utility that remote checks for the presence of BOM.
I am trying to get a session created by a browser call to be used by a command line cli->curl php call (in this case, both calls to the same server and php.ini), for a set of flexible media import routines,
but the cli->curl call always starts a new session despite me putting PHPSESSID=validID as the first parameter for the url called by curl.
I was able to fix it by calling session_id($_GET[‘PHPSESSID’]) before calling session_start() in the script called via curl.
Источник