本地正常的PHP Cookie在虚拟主机无法设置,请求排查帮助
Hey there! Let's break down why your cookies aren't working on the virtual host but work locally, and fix this step by step. I'll go through the most common issues and show you exactly what to adjust in your code.
1. Fix the Cookie Path & Domain (Most Common Issue)
When running locally, your app is probably at the root of your server (like http://localhost/), so cookies default to the root path automatically. But on a virtual host, your app might live in a subdirectory, or the server requires explicit domain/path configuration for cookies to be accessible site-wide.
Your current setcookie calls don't specify these critical parameters, which can restrict cookies to only the current directory. Let's update them:
Before:
setcookie('id_users', $row['id_users'], time() + (60*60*24*30)); setcookie('email', $row['email'], time() + (60*60*24*30));
After:
// Get your virtual host's domain automatically $domain = $_SERVER['HTTP_HOST']; // Check if the site uses HTTPS (most virtual hosts enforce this now) $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; // Set cookies with proper cross-site accessibility and security setcookie('id_users', $row['id_users'], [ 'expires' => time() + (60*60*24*30), // 30-day expiration 'path' => '/', // Make cookie accessible across the entire site 'domain' => $domain, // Bind to your virtual host's domain 'secure' => $is_https, // Only send over HTTPS if enabled 'httponly' => true, // Block JavaScript access (prevents XSS attacks) 'samesite' => 'Lax' // Comply with modern browser cookie rules ]); setcookie('email', $row['email'], [ 'expires' => time() + (60*60*24*30), 'path' => '/', 'domain' => $domain, 'secure' => $is_https, 'httponly' => true, 'samesite' => 'Lax' ]);
This ensures cookies work across all pages of your site, regardless of subdirectories, and plays nice with HTTPS (a common requirement on virtual hosts).
2. Fix the Menu's Cookie Check Logic
Looking at your menu code, there's a subtle bug in the authorization check:
if(!isset($_COOKIE['email']) && !isset($_COOKIE['password'])){
You never set a password cookie in your login code! So !isset($_COOKIE['password']) is always true. This makes the condition fragile—let's simplify it to only check the cookie you actually set during login:
Updated Menu Code:
<ul class="menu"> <li><a href="index.php">Главная</a></li> <li><a href="about.php">О нас</a></li> <li><a href="materials.php">Материалы</a></li> <li><a href="recomendations.php">Рекомендации</a></li> <li><a href="Contacts.php">Контакты</a></li> <?php // Only check the email cookie you set during login if(!isset($_COOKIE['email'])){ ?> <li><a href="form_auth.php">Authorisation</a></li> <?php }else{ ?> <li><a href="admin.php">Profile</a></li> <li><a href="exit_accaunt.php">Exit</a></li> <?php } ?> </ul>
This removes the unnecessary check for a non-existent cookie, making your menu logic reliable and easy to debug.
3. Ensure No Output Before Setting Cookies
PHP requires that cookies (which are HTTP headers) are sent before any content (HTML, echo statements, even whitespace). If there's any output before setcookie, the cookies won't be saved.
Check these things:
- Your PHP file has no leading whitespace or empty lines before
<?php. - No
echostatements,print, or HTML code appear before you callsetcookie(your current code hasechoaftersetcookie, which is fine). - If your file uses UTF-8 encoding, save it as UTF-8 without BOM (some text editors add a hidden BOM character that counts as output).
If you're unsure, enable output buffering at the top of your login file to delay content output until headers are sent:
<?php ob_start(); // Enable output buffering to avoid header issues // Rest of your code...
4. Check Virtual Host PHP Configuration
Sometimes virtual hosts have strict settings that affect cookies:
output_buffering: If disabled, even a single space before<?phpbreaks cookies. Verify it's enabled withphpinfo()(create a file with<?php phpinfo(); ?>and upload it to your host) or enable it via.htaccessif allowed:php_value output_buffering Onsession.cookie_secure: If your host uses HTTPS, this setting may block non-secure cookies. That's why we added thesecureparameter in step 1.
5. Test Cookies Directly
To debug, upload this test file to your virtual host to see if cookies are being set:
<?php // Test setting a basic cookie setcookie('test_cookie', 'hello_world', [ 'expires' => time() + 3600, 'path' => '/', 'domain' => $_SERVER['HTTP_HOST'], 'secure' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on', 'samesite' => 'Lax' ]); // Check if the cookie exists if(isset($_COOKIE['test_cookie'])){ echo "Cookie works! Value: " . $_COOKIE['test_cookie']; }else{ echo "Cookie not set. Check your browser's dev tools > Application > Cookies"; } ?>
Visit the file, then check your browser's dev tools (Application tab > Cookies) to see if the test cookie appears. If not, look for errors in the Console tab.
Try these steps in order—most likely, fixing the cookie parameters and menu logic will resolve your issue. Let me know if you hit any snags!
内容的提问来源于stack exchange,提问作者Sad

