Почему мои файлы cookie не установлены?

У меня есть следующая функция PHP:

function validateUser($username){
    session_regenerate_id (); 
    $_SESSION['valid'] = 1;
    $_SESSION['username'] = $username;
    setcookie('username2',$username,time()+60*60*24*365);
    header("Location: ../new.php");
}

И затем я получаю файл cookie:

echo $_COOKIE['username2']; exit();

(я только ставил exit() для целей отладки)

Только проблема, она выходит пустая. Любые идеи?

UPDATE: Так вызывается функция:

    if(mysql_num_rows($queryreg) != 0){
    $row = mysql_fetch_array($queryreg,MYSQL_ASSOC);
    $hash = hash('sha256', $row['salt'] . hash('sha256', $password));
    if($hash == $row['password']) {
        if($row['confirm'] == 1){
            if(isset($remember)){
                setcookie('username',$username,time()+60*60*24*365);
                setcookie('password',$password,time()+60*60*24*365);
            } else {
                setcookie('username','',time()-3600);
                setcookie('password','',time()-3600);
            }
            validateUser($username);

Я не включал все инструкции if() для сохранения некоторого пробела.

Ответ 1

попробуйте добавить путь =/, так что cookie будет работать для всего сайта не только текущего каталога (который раньше меня поймал)

Пример

setcookie('password',$password,time()+60*60*24*365, '/'); 

также убедитесь, что файл cookie - это первое, что выводится как это было рекомендовано в справочнике php (это тоже меня поймало)

Как и другие заголовки, файлы cookie должны быть отправлены до выхода из вашего script (это ограничение протокола).

Ответ 2

Почему у вас возникла эта проблема

Проблема возникает из-за того, что setcookie() не устанавливает cookie немедленно, он отправляет заголовки, чтобы браузер устанавливал файлы cookie. Это означает, что для текущей загрузки страницы setcookie() не генерирует никаких $_COOKIE.

Когда браузер позже запрашивает страницу, он отправляет файлы cookie в заголовки, чтобы PHP мог получить их в виде $_COOKIE.

Простое, старое решение

О решениях, очевидном:

setcookie('username',$username,time()+60*60*24*365);
// 'Force' the cookie to exists
$_COOKIE['username'] = $username;

Лучшее решение

Я создал класс Cookie, который решает проблемы, которые устанавливают sharecookie() и $_COOKIE:

// Class that abstracts both the $_COOKIE and setcookie()
class Cookie
  {
  // The array that stores the cookie
  protected $data = array();

  // Expiration time from now
  protected $expire;
  // Domain for the website
  protected $domain;

  // Default expiration is 28 days (28 * 3600 * 24 = 2419200).
  // Parameters:
  //   $cookie: $_COOKIE variable
  //   $expire: expiration time for the cookie in seconds
  //   $domain: domain for the application `example.com`, `test.com`
  public function __construct($cookie, $expire = 2419200, $domain = null)
    {
    // Set up the data of this cookie
    $this->data = $cookie;

    $this->expire = $expire;

    if ($domain)
      $this->domain = $domain;
    else
      {
      $this->domain = 
        isset($_SERVER['HTTP_X_FORWARDED_HOST']) ?
        $_SERVER['HTTP_X_FORWARDED_HOST'] :
        isset($_SERVER['HTTP_HOST']) ?
          $_SERVER['HTTP_HOST'] :
          $_SERVER['SERVER_NAME'];
      }
    }

  public function __get($name)
    {
    return (isset($this->data[$name])) ?
      $this->data[$name] :
      "";
    }

  public function __set($name, $value = null)
    {
    // Check whether the headers are already sent or not
    if (headers_sent())
      throw new Exception("Can't change cookie " . $name . " after sending headers.");

    // Delete the cookie
    if (!$value)
      {
      setcookie($name, null, time() - 10, '/', '.' . $this->domain, false, true);
      unset($this->data[$name]);
      unset($_COOKIE[$name]);
      }

    else
      {
      // Set the actual cookie
      setcookie($name, $value, time() + $this->expire, '/', $this->domain, false, true);
      $this->data[$name] = $value;
      $_COOKIE[$name] = $value;
      }
    }
  }

Затем вы можете использовать его следующим образом:

$Cookie = new Cookie($_COOKIE);
$User = $Cookie->user;
$LastVisit = $Cookie->last;
$Cookie->last = time();

И, конечно же, вы должны пройти его. Гораздо лучше, чем глобальные.

Ответ 3

Вот общий синтаксис setcookie

setcookie(name,value,expire,path,domain,secure); 

Посмотрите на третий аргумент, если вы его не установили, script перенесет его в текущий рабочий каталог. Поэтому, если вы установите cookie без установки пути в a.com/b/setcookie.php, cookie будет недоступен для a.com/checkcookie.php. Что вы делаете, это установить cookie в подпапку и перенаправить на родительскую папку, посмотрите ../, где она недоступна, поэтому проблема. Как этого избежать? Обычная процедура заключается в том, чтобы указать путь /, в вашем случае поставьте / как четвертый параметр. Пятый аргумент для вашего файла cookie будет безопасным. http://www.php.net/setcookie имеет больше объяснений. Это должно решить вашу проблему. Настройка пути домена к domain.com сделает cookie доступным для всего под domain.com, но не до something.domain.com. Задайте значение домена .domain.com, посмотрите на точку, предшествующую domain.com, и сделайте ее доступной через anything.domain.com. НТН!

Ответ 4

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

Следующий пример может быть применим к некоторым программистам, имеющим то, что кажется проблемой иллюзорного параметра cookie в результате неправильного использования header_remove();

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

Вы можете найти, когда возитесь с тем, что ваш cookie внезапно работает по неизвестной причине:

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

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

Если вы использовали команду header_remove() для изменения иерархии кодов ответа HTTP для DOM Scripting, вы можете быстро решить этот конфликт заголовка заголовка cookie, используя следующее, чтобы явно очистить коды ответов:

 header_remove('HTTP/1.0');