Problem: verified cookie set in PHP and visible in developer tools is not detected by PHP for Safari. Same script is working fine in Chrome and Firefox.
Simplified example that illustrates the problem:
setcookie( 'cookiename', '1', time()+1200, '/' );
Reloading the page or loading other pages shows the cookie visible in the browser storage with the correct value in Safari. PHP on any page returns an empty $_COOKIE
array but only in Safari.
var_dump( $_COOKIE );
array(0) {}
... in JS
document.cookie
I've read at least a dozen Safari cookie issues and solutions all over the web, including these:
$_COOKIE not working in Safari iOS
Not able to read cookie on JS side on Safari/iPhone
None appear to be relevant to the issue I'm facing.
TLDR: cookie is verified set correctly in Safari but PHP or JS to read it shows empty $_COOKIE
array.
EDIT: suggested solution on the most similar problem I have found: Use the assoc array options as detailed in docs: https://www.php.net/manual/en/function.setcookie.php
setcookie('cookiename', '1', [
'expires' => time()+1200,
'path' => '/',
'domain' => 'domain.com',
'secure' => false,
'httponly' => false,
'samesite' => 'Lax',
]);
RESULT: Safari functioning as expected locally, but not on WPE server though the cookie is still visibly set but not read on subsequent page loads.
The solution for Safari was very simple, but I do not understand why it was the solution.
Changing this:
setcookie( 'cookiename', '1', time()+1200, '/' );
... to this:
setcookie( 'cookiename', '1', time()+1200, '' );
Using an empty PATH parameter and PHP and JS both recognize the cookie and value.
I would love to know why this is the solution for Safari if anyone can elaborate!
EDIT: problem persists with above. Late night test appeared to show a solution but failing this morning...
EDIT 2: solved my own very localized use case by setting the PATH parameter on the cookie to the current page slug. I am only preventing a form from displaying again on page reload. Setting the PATH explicitly to the current page slug and Safari recognizes the cookie on that page only.
$path = $_SERVER['REQUEST_URI'];
setcookie( 'cookiename', '1', time()+1200, $path );