web-dev-qa-db-fra.com

Pourquoi mes cookies ne sont-ils pas installés?

J'ai la fonction PHP suivante:

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

Et puis je vais chercher le cookie:

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

(Je ne mets que exit() à des fins de débogage)

Seul problème, ça sort en blanc. Des idées?

METTRE À JOUR: Voici comment la fonction s'appelle:

    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);

Je n'ai pas inclus toutes les instructions if() pour économiser de l'espace.

16
Jason

essayez d'ajouter le chemin = /, de sorte que le cookie fonctionne pour l'ensemble du site, et pas uniquement pour le répertoire en cours (qui m'a déjà surpris

exemple

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

assurez-vous également que le cookie est la première chose à afficher. Comme indiqué dans le manuel php (cela m’a déjà surpris auparavant)

Comme les autres en-têtes, les cookies doivent être envoyés avant toute sortie de votre fichier script (il s'agit d'une restriction de protocole).

35
bumperbox

Pourquoi vous rencontrez ce problème

Le problème vient du fait que setcookie () ne définit pas les cookies immédiatement , il envoie les en-têtes afin que le navigateur mette les cookies. Cela signifie que pour le chargement de la page en cours, setcookie () ne générera aucun $_COOKIE.

Lorsque le navigateur demande ultérieurement une page, il envoie les cookies dans les en-têtes afin que PHP puisse les récupérer sous la forme $ _COOKIE.

Simple, vieux solution

Au sujet des solutions, l’évident:

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

Une meilleure solution

J'ai créé une classe, Cookie, qui résout les problèmes rencontrés par setcookie () et $ _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;
      }
    }
  }

Ensuite, vous pouvez l'utiliser comme ceci:

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

Et bien sûr, vous devez le faire circuler. Bien mieux que d'avoir des globals.

17
Francisco Presencia

Voici la syntaxe générale de setcookie

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

Regardez le troisième argument, si vous ne le définissez pas, le script le prendra dans le répertoire de travail courant. Donc, si vous définissez un cookie sans définir de chemin d'accès sur a.com/b/setcookie.php, le cookie ne sera pas disponible pour a.com/checkcookie.php. Ce que vous êtes en train de faire, c'est de définir un cookie dans un sous-dossier et de le rediriger vers un dossier parent. Consultez ../, où il n'est pas disponible, d'où le problème. Comment éviter cela? La procédure normale consiste à fournir un chemin qui est /, dans votre cas, fournissez / en tant que quatrième paramètre. Le cinquième argument pour votre cookie le sécurisera. http://www.php.net/setcookie a plus d'explications. Cela devrait résoudre votre problème. Si vous définissez le chemin du domaine sur domain.com, le cookie sera disponible pour tout ce qui est sous domain.com mais pas pour something.domain.com. Définissez la valeur du domaine sur .domain.com, regardez le point qui précède domain.com, le rendra disponible sur anything.domain.com. HTH!

4
Kumar

J'ai pensé ajouter une autre raison possible pour laquelle un cookie peut ne pas être défini ou afficher un comportement fonctionnel aléatoire.

Le cas suivant peut s’appliquer à certains programmeurs ayant ce qui semble être un problème illusoire de définition de cookies en raison de l’utilisation incorrecte de header_remove () ;

Si vous essayez de définir un cookie avant appelant header_remove () , le cookie ne sera jamais créé car vous avez également détruit l'en-tête défini pour créer le cookie avant que l'instruction ne soit mise en mémoire tampon par le client. .

Lorsque vous vous amusez, vous pouvez constater que votre cookie fonctionne soudainement pour une raison inconnue:

Lors d'une première utilisation, si vous définissez un cookie et que vous n'appelez pas du tout header_remove (), à la deuxième exécution, vous appelez header_remove (), votre cookie sera désormais toujours défini.

La même chose s'applique également si vous essayez de modifier une valeur de cookie avant header_remove (), vous échouerez à nouveau, car les modifications que vous essayez d'apporter seront effacées avant qu'elles ne soient réellement mises en mémoire tampon par l'utilisateur . Vous devez définir des cookies. et tous les autres en-têtes après le header_remove () pas avant.

Si vous utilisiez header_remove () pour modifier une hiérarchie de codes de réponse HTTP pour les scripts DOM, vous pouvez résoudre rapidement ce conflit d'effacement d'en-tête de cookie en utilisant ce qui suit pour supprimer explicitement les codes de réponse uniquement:

 header_remove('HTTP/1.0');
3
Marc Newton

Cela nécessite que vous passiez des appels à cette fonction avant toute sortie, y compris les balises et les espaces.

voici à quoi ressemble la structure

<?php
$cookie_name = "user";
$cookie_value = "Ahmed Moftah";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
?>
<?php
if(!isset($_COOKIE[$cookie_name])) {
    echo "Cookie named '" . $cookie_name . "' is not set!";
} else {
    echo "Cookie '" . $cookie_name . "' is set!<br>";
    echo "Value is: " . $_COOKIE[$cookie_name];
}
?>
<html>
<body>



</body>
</html>
0
Moftah