Предотвратите php session_start(), чтобы отправить файл cookie

Я хотел бы знать, есть ли способ предотвратить отправку cookie PHP при вызове session_start().

Мой вариант использования предназначен для оптимизации сайта:

  • (1a) Сначала я открываю заголовки сеанса/отправки.
  • (1b) Затем создайте и выведите некоторое текстовое содержимое.
  • (1c) Чтобы улучшить сеанс чтения/записи, я вызываю "session_write_close", как только мне больше не нужно писать в сеансе.
  • (2) Наконец, у меня есть процесс рендеринга после страницы (для статистики), для которого требуется доступ на запись к сеансу. Сеанс закрыт, я не могу снова вызвать session_start(), так как он отправляет файл cookie, и он опаздывает на это. Это сложный процесс вычисления, поэтому я должен сделать это после отправки страницы клиенту.

Клиент уже получил сеансовый файл cookie. Поэтому мне не нужно session_start() отправить новый (и избыточный).

Кто-нибудь знает способ перехватить файл cookie или что-то подобное? Конечно, я хочу избежать "Не могу отправить сессию cookie - уже отправленные заголовки". Эта ошибка является невидимой для пользователя, потому что страница уже визуализирована, но в журналах она выглядит уродливой.

Мой вопрос кажется избыточным, но это не так. Я знаю, как работают заголовки и содержимое (сначала отправляйте заголовки, потом контент). Это просто, что PHP не позволяет мне делать то, что я хочу.

Ответ 1

Я хотел бы знать, есть ли способ предотвратить отправку cookie PHP при вызове session_start().

Да, есть, говоря PHP, чтобы не использовать файлы cookie для сеансов. Параметр PHP session.use_cookies:

ini_set('session.use_cookies', 0); # disable session cookies
session_start();

По умолчанию куки включены, потому что они считаются более безопасными, а затем используют параметры URL (см. Сессии и безопасность & shy; Docs).

(2) Наконец, у меня есть процесс рендеринга после страницы (для статистики), для которого требуется доступ на запись к сеансу. Сеанс закрыт, я не могу снова вызвать session_start(), так как он отправляет файл cookie, и он опаздывает на это. Это сложный процесс вычисления, поэтому я должен сделать это после того, как страница будет отправлена ​​клиенту.

Вероятно, можно сказать PHP, что cookie уже установлен, добавив его в $_COOKIE суперглобальный массив & shy; Docs. Я никогда не экспериментировал с ним, но если вы используете session_start(), и PHP видит, что cookie сеанса уже установлен (браузером, а не PHP, $_COOKIE представляют куки файлы браузера), он не будет отправлять заголовки ( снова), чтобы установить файл cookie (который, как я понимаю, вы хотите).


Изменить: Некоторое испытание script для воспроизведения:

<?php
header('Content-Type: text/plain;');

echo "Incomming Cookies:\n";
print_r($_COOKIE);

// to simulate that this is a new session, the session cookie is removed
// which makes PHP think it is a new session when invoking session_start()
// unset($_COOKIE['PHPSESSID']);

// run the first session
session_start(); // creates the session cookie (as we don't have one yet)
printf("Session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['variable'] = isset($_SESSION['variable']) ? $_SESSION['variable']++ : 0;
session_commit();

printf("Session has been closed, remaining id is: %s\n", session_id());

// visual confirmation that session cookie has been created
echo "Outgoing Cookies:\n";
print_r(headers_list());

// run the second session
ini_set('session.use_cookies', 0); # disable session cookies
session_start();
printf("Second session %s has been started: %s\n", session_name(), session_id());
var_dump($_SESSION);
$_SESSION['2nd-variable'] = isset($_SESSION['2nd-variable']) ? $_SESSION['2nd-variable']++ : 0;
session_commit();

Вам нужно позвонить ему с помощью веб-браузера (и PHP-сессии должны быть настроены для работы).

Ответ 2

Я думал, что должен упомянуть еще один отличный способ предотвратить отправку заголовков файлов cookie (и кеш-лимитера) при вызове session_start.

В вызове session_start используется массив параметров, в котором вы можете установить любой из сеансов. префиксные переменные, и вы можете отключить эти вещи только для этого вызова.

session_start(array(
   'use_cookies' => '0',
   'cache_limiter' => ''
));

Обратите внимание, что use_cookies не позволяет отправлять cookie, а установка ограничителя кеша в пустую строку не позволяет ему обновлять заголовки кеша (не самая лучшая задокументированная функция).

Вот два уведомления, которые это исправит (это полезно, когда вам нужно работать через несколько сеансов).

Warning: session_start(): Cannot send session cookie - headers already sent

и

Warning: session_start(): Cannot send session cache limiter - headers already sent

Ответ 3

Вы можете использовать ob_start() для буферизации заголовков/содержимого, вы можете очистить содержимое буфера, используя ob_clean()