Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

368
Views
Remove duplicate "Set-Cookie" header from PHP response

This is an example script from a larger application, but shows the general process of what I'm trying to do. If I have the following script:

<?php
ob_start();

setcookie('test1', 'first');
setcookie('test1', 'second');
setcookie('test1', 'third');
setcookie('test2', 'keep');

//TODO remove duplicate test1 from headers

ob_end_clean();
die('end test');

I get the following response (as viewed via Fiddler):

HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

end test

The problem is that Set-Cookie: test1... exists 3 different times, therefore increasing the header size unnecessarily. (Again, this is a simplified example - in reality, I'm dealing with ~10 duplicate cookies in the ~800-byte range.)

Is there anything I can write in place of the TODO that would get rid of the header either completely or so it only shows once? i.e. the following is my end goal:

HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

end test

though the Set-Cookie: test1=third could not exist too and that's fine, but Set-Cookie: test2=keep needs to remain. When I try setcookie('test1', '', 1); to delete the cookie, it adds an additional header to mark it as expired:

Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Set-Cookie: test1=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0

And if I try removing the header like:

if (!headers_sent()) {
    foreach (headers_list() as $header) {
        if (stripos($header, 'Set-Cookie: test1') !== false) {
            header_remove('Set-Cookie');
        }
    }
}

it removes all Set-Cookie headers when I only want test1 removed.

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

As you suggested in that last block of code, the headers_list() function could be used to check what headers have been sent. Using that, the last values for each cookie could be stored in an associative array. The names and values can be extracted using explode() (along with trim()).

When multiple cookies with the same name have been detected, we can use the header_remove() call like you had, but then set the cookies to the final values. See the example below, as well as this example phpfiddle.

if (!headers_sent()) {
    $cookiesSet = []; //associative array to store the last value for each cookie
    $rectifyCookies = false; //multiple values detected for same cookie name

    foreach (headers_list() as $header) {
        if (stripos($header, 'Set-Cookie:') !== false) {
            list($setCookie, $cookieValue) = explode(':', $header);
            list($cookieName, $cookieValue) = explode('=', trim($cookieValue));
            if (array_key_exists($cookieName, $cookiesSet)) {
                $rectifyCookies = true;
            }
            $cookiesSet[$cookieName] = $cookieValue;
        }
    }
    if ($rectifyCookies) {
        header_remove('Set-Cookie');
        foreach($cookiesSet as $cookieName => $cookieValue) {
            //might need to consider optional 3rd - 8th parameters 
            setcookie($cookieName, $cookieValue);
        }
    }
}

Output:

Cache-Control max-age=0, no-cache, no-store, must-revalidate
Connection keep-alive
Content-Encoding gzip
Content-Type text/html; charset=utf-8
Date Wed, 26 Apr 2017 15:31:33 GMT
Expires Wed, 11 Jan 1984 05:00:00 GMT
Pragma no-cache
Server nginx
Set-Cookie test1=third
                     test2=keep
Transfer-Encoding chunked
Vary Accept-Encoding

about 4 years ago · Santiago Trujillo Report

0

I don't understand why you think that the cookie removing code you showed us would remove the setcookie for test2.

If your code is setting the same cookie multiple times then you need to change your code so it stops setting the cookie multiple times! Anything else is a sloppy workaround.

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!