Ankündigung

Einklappen
Keine Ankündigung bisher.

[CookieManager] Cookie wird nicht gesetzt

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [CookieManager] Cookie wird nicht gesetzt

    Hallo zusammen,

    im Rahmen der 1.8er Serie des APF (Roadmap :: Adventure PHP Framework (APF)) bin ich dabei, mich mit dem Thema Cookie-Handling zu beschäftigen. Analog zum SessionManager möchte ich die Möglichkeit bieten Namespace-basierte Cookie-Verwaltung auf einfachem Weg anzubieten.

    Dazu habe ich die relevanten RFCs und das PHP-Manual konsultiert und einige Ansätze gefunden, wie Cookies zu senden sind. Ich habe beide Möglichkeiten (header('Set-Cookie: ...') und setcookie()) getestet - ohne Erfolg. Ich sehe den Set-Cookie-Header zwar im Protokoll-Header, ein

    PHP-Code:
    print_r($_COOKIE); 
    zeigt mir jedoch nicht den gewünschten Inhalt an.

    Hier die Funktion, die ich mir aus einer der user contributed notes unter PHP: setcookie - Manual kopiert und ein wenig modifiziert habe:

    PHP-Code:
       function createCookie($name$value=''$maxage=0$path='',$domain=''$secure=false$HTTPOnly=false){
         if(
    is_array($name)){
             list(
    $k,$v)    =    each($name);

                 
    $name    =    $k.'['.$v.']';

         }
         
    $ob ini_get('output_buffering');
         
    // Abort the method if headers have already been sent, except when output buffering has been enabled
         
    if ( headers_sent() && (bool) $ob === false || strtolower($ob) == 'off' )
             return 
    false;
         if ( !empty(
    $domain) )
         {
             
    // Fix the domain to accept domains with and without 'www.'.
             
    if ( strtolowersubstr($domain04) ) == 'www.' $domain substr($domain4);
             
    // Add the dot prefix to ensure compatibility with subdomains
             
    if ( substr($domain01) != '.' && $domain != 'localhost' $domain '.'.$domain;
             
    // Remove port information.
             
    $port strpos($domain':');
             if ( 
    $port !== false $domain substr($domain0$port);
         }

         
    // Prevent "headers already sent" error with utf8 support (BOM)
         //if ( utf8_support ) header('Content-Type: text/html; charset=utf-8');
         
    if(is_array($name))
         {
             
    header('Set-Cookie: '.$name.'='.rawurlencode($value)
                                     .(empty(
    $domain) ? '' '; Domain='.$domain)
                                     .(empty(
    $maxage) ? '' '; Max-Age='.$maxage)
                                     .(empty(
    $path) ? '' '; Path='.$path)
                                     .(!
    $secure '' '; Secure')
                                     .(!
    $HTTPOnly '' '; HttpOnly'), false);
         }else{
             
    header('Set-Cookie: '.rawurlencode($name).'='.rawurlencode($value)
                                     .(empty(
    $domain) ? '' '; Domain='.$domain)
                                     .(empty(
    $maxage) ? '' '; Max-Age='.$maxage)
                                     .(empty(
    $path) ? '' '; Path='.$path)
                                     .(!
    $secure '' '; Secure')
                                     .(!
    $HTTPOnly '' '; HttpOnly'), false);
         }
         return 
    true;
       }

       echo 
    $expires date('D, d-M-Y H:i:s \G\M\T',time() + 86400);

       
    createCookie('test_key','test_value',$expires,'/','localhost');
       echo 
    '<br /><br />'.printObject($_COOKIE); 
    Diese Variante funktioniert genau so wenig wie die Implementierung meines CookieManager, der wie folgt versucht ein Cookie zu setzen:

    PHP-Code:
          function createCookie($key,$value,$expire null,$domain null){

             
    // set default expiration if not given as an argument
             
    if($expire === null){
                
    $expire time() + $this->__ExpireTime;
              
    // end if
             
    }

             
    // set default domain (=current) if not given as an argument
             
    if($domain === null){
                
    $domain $_SERVER['HTTP_HOST'];
              
    // end if
             
    }

             
    // call setcookie and return the result
             
    return setcookie($key,$value,$expire,'/',$domain);

           
    // end function
          

    Hat irgendjemand mehr Erfahrung mit Cookies wie ich und kann mir einen Tipp geben? Habe ich in meiner Implementierung einen Denkfehler?

    Any advice including RTFMs are welcome!

  • #2
    Das Feld $_COOKIE ist erst beim nächsten Request gefüllt, nämlich dann wenn der Browser den Header Cookie gesendet hat. Sollte das etwa dein Denkfehler sein? Ich fände es äußerst seltsam.

    Kommentar


    • #3
      Ich habe mir deinen Code nochmals genauer angesehen und folgendes festgestellt:
      Der Max-Age-Header ist ungültig, weshalb das Cookie nicht angenommen wird. Max-Age != Expires. Expires ist der Header, der einen GMT-String fordert. Max-Age hingegen will einen Integer-Wert haben, der festlegt, in wie vielen Sekunden das Cookie ablaufen wird (nur HTTP 1.1, nicht 1.0).
      Das andere Problem ist der Domain-Header. Dieser funktioniert auf dem localhost nur mit dem Opera. Die anderen haben Probleme mit Domains, die keine Punkte beinhalten oder localhost heißen oder what ever. Hängt sicherlich damit zusammen:
      The IESG notes that this mechanism makes use of the .local top-level
      domain (TLD) internally when handling host names that don't contain
      any dots, and that this mechanism might not work in the expected way
      should an actual .local TLD ever be registered.
      Auf einer anderen Domain sollte das Domain-Attribut auch in anderen Browsern funktionieren, auf dem localhost musst du also die Domain-Angabe weglassen.

      Kommentar


      • #4
        Hi,

        danke für die Info, ich schau mir das morgen nochmal genauer an, ist schon spät.

        Kommentar

        Lädt...
        X