PHP setcookie 在生产服务器上 "echo" 后不起作用(它在本地主机上起作用)

PHP setcookie doesn't work after "echo" on production server (it does work on localhost)

我的网站有一个相当不错的类似系统。一旦用户点击 ❤️,我的 script.js 就会向我的 PHP 服务器发送包含博客 post 路径名的 Ajax,该服务器会检查用户是否已经喜欢它(如果是这样,则有一个相应的 cookie)。如果不是,它会读取我的 like.json 的内容并查找 post 的计数,然后将其增加 1。之后,服务器给用户一个 cookie,说他已经喜欢这个 post.

现在我告诉你:在我的本地主机上一切正常。但是当我将所有内容上传到生产服务器时,它无法设置“已经喜欢”cookie。

首先,让我们看看所有的代码文件:

script.js 发送 Ajax:

var url = window.location.pathname;

$.ajax({
    type: "POST",
    url: 'like.php',
    data: { "liked": url },
    success: function(response){
        
    }
});

这是 PHP 文件:

<?php

setcookie('why-doesnt-work-anything', 'no-idea', time() + (86400 * 30), NULL, NULL, TRUE, NULL);

$url = $_POST['liked'];

$filename = "like.json";
$fd = fopen ($filename, "r");
$contents = fread ($fd, filesize($filename));
fclose ($fd);

$originalcontents = $contents;
$contents = json_decode($contents);
$contents->$url = $contents->$url + 1;

setcookie('nothing-works', 'no-clue', time() + (86400 * 30), NULL, NULL, TRUE, NULL);

echo $contents->$url;

setcookie('doesnt-work', 'i-dont-know-why', time() + (86400 * 30), NULL, NULL, TRUE, NULL);

$contents = json_encode($contents);

$urls = $url;

if($_COOKIE['like'] != undefined && $_COOKIE['like'] != ''){
    $urls = $url . ',' . $_COOKIE['like'];
}

if(in_array($url,explode(',',$_COOKIE['like']))){
    $urls = $_COOKIE['like'];
    $contents = $originalcontents;
}

setcookie('like', $urls, time() + (86400 * 30), NULL, NULL, TRUE, NULL); // the actual liked cookie

$fp = fopen ($filename, "w");
fwrite ($fp,$contents);
fclose ($fp);

?>

这是“激动人心”的部分:这与一般的 cookie 无关。如您所见,我创建了 3 个测试 cookie。记住:在我的本地主机上,一切正常。但是在生产服务器上,在 echo 行之后所有设置 cookie 的尝试都失败了。前 2 个 cookie 有效,但第 3 个无效。

我认为这不是我的托管服务提供商 (1&1) 的错误。是因为 PHP 版本不同吗?或者他妈的问题是什么?

感谢您的帮助!

一旦你回显了一些东西,你就不能再设置 cookie,除非在你的环境中默认启用了输出缓冲;你的本地主机可能是什么情况。

documentation 说:

Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including and tags as well as any whitespace.

还有:

Note: You can use output buffering to send output prior to the call of this function, with the overhead of all of your output to the browser being buffered in the server until you send it. You can do this by calling ob_start() and ob_end_flush() in your script, or setting the output_buffering configuration directive on in your php.ini or server configuration files.

PS:您还必须考虑 Niet the Dark Absol 关于在这种情况下使用 cookie 的评论。