PHP 的 setcookie() 函数不起作用。怎么了?

PHP's setcookie() function is not working. What's wrong?

我真的需要一些帮助。我写了这个脚本来跟踪我网站的流量。我 使用 cookies 来帮助服务器知道客户端何时访问过某个页面,这让我可以按两个来跟踪访问者(2) counters/categories:UNIQUE 命中和 "REFRESH" 命中。

我将信息存储在以日期命名的目录中。例如,位于 www.example.com/counter/unique/2015/12/31/about 的文件将存储类似 62 的数字,这意味着我在 2015 年 12 月 31 日对 about.php 页面进行了 62 次唯一点击。

每个页面调用脚本counter.php。一切似乎都正常,但我的两个计数器继续读取相同的数字,好像每次命中都是独一无二的。看到这两组数字我就知道不对了,我刷新了几次索引页确认了。这意味着没有设置 cookie。 counter.php 中的 PHP 脚本测试 cookie 是否已设置。我也一直在检查我的浏览器设置中的 cookie,但它没有显示任何 cookie。我刷新每个页面几次,re-check 多次刷新 cookie,但仍然没有运气!

这到底是怎么回事?!?它之前是有效的!

下面展示了每个页面如何调用counter.php脚本:

http://www.example.com/index.php:

<?php
    include_once("log/counter.php");
?>
<!doctype html>
<html>
...
</html>

以下是我的 PHP 代码 counter.php:

http://www.example.com/log/counter.php

<?php

    // THIS LINE WAS NOT PART OF MY ORIGINAL SCRIPT
    ob_start();

    // THIS IS THE PAGE THAT IS CALLING THIS SCRIPT,
    // FOR EXAMPLE: ABOUT, INDEX, CONTACT, ETC.
    $page = basename($_SERVER["SCRIPT_FILENAME"], ".php");

    // THE DIRECTORY WHERE THIS SCRIPT IS LOCATED
    // RELEVANT TO THE CALLING PAGE
    $cwd = dirname(__FILE__) . "/counter/";

    date_default_timezone_set('America/Chicago');
        // TIMEZONE FOR HOUSTON, TEXAS. THIS WAY, ALL
        // DATE & TIME INFO IS SET IN THAT TIMEZONE

    $currentYear = date("Y");   // EX: 2015
    $currentMonth = date("m");  // EX: 12
    $currentDay = date("d");    // EX: 31

    // THIS PREPARES THE DIRECTORY FOR TODAY'S DATE
    $today = $currentMonth."/".$currentDay."/".$currentYear;
    $current = $currentYear."/".$currentMonth."/".$currentDay."/";

    $currentHour = date("H");
    $currentMinute = date("i");
    $currentSecond = date("s");

    // THE FOLLOWING IS USED FOR THE COOKIE EXPIRATION PARAM

    $secondsRemaining = 60 - $currentSecond;
    $minutesRemaining = 59 - $currentMinute;
    $hoursRemaining = 23 - $currentHour;

    $totalSecondsRemaining = ($hoursRemaining * 60 * 60) + ($minutesRemaining * 60) + $secondsRemaining;

    if ($totalSecondsRemaining<=0) { $totalSecondsRemaining = 86400; }
        // 86400 SECONDS = 24 HOURS / 1 DAY

    $ucFile = $cwd . "unique/" . $current . $page;      // UNIQUE-HITS COUNTER
    $rcFile = $cwd . "refresh/" . $current . $page;     // REFRESH-HITS COUNTER

        // MAKE SURE ALL DIRECTORIES EXIST
        if (!file_exists($cwd."unique/")){
            mkdir($cwd."unique", 0755);
        }
        if (!file_exists($cwd."unique/".$currentYear)){
            mkdir($cwd."unique/".$currentYear, 0755);
        }
        if (!file_exists($cwd."unique/".$currentYear."/".$currentMonth)){
            mkdir($cwd."unique/".$currentYear."/".$currentMonth, 0755);
        }
        if (!file_exists($cwd."unique/".$currentYear."/".$currentMonth."/".$currentDay)){
            mkdir($cwd."unique/".$currentYear."/".$currentMonth."/".$currentDay, 0755);
        }
        if (!file_exists($cwd."refresh/")){
            mkdir($cwd."refresh", 0755);
        }
        if (!file_exists($cwd."refresh/".$currentYear)){
            mkdir($cwd."refresh/".$currentYear, 0755);
        }
        if (!file_exists($cwd."refresh/".$currentYear."/".$currentMonth)){
            mkdir($cwd."refresh/".$currentYear."/".$currentMonth, 0755);
        }
        if (!file_exists($cwd."refresh/".$currentYear."/".$currentMonth."/".$currentDay)){
            mkdir($cwd."refresh/".$currentYear."/".$currentMonth."/".$currentDay, 0755);
        }
        // ALL DIRECTORIES NOW EXIST. SO FAR, NO PROBLEMS!


    // UNIQUE COUNTER...
    if (!isset($_COOKIE[$page])){          // THIS ALWAYS GETS CALLED...
        if (file_exists($ucFile)){         // IF PAGE HAS BEEN COUNTED...
            $file = fopen($ucFile, "r+");  //  1. OPEN THE COUNTER FILE FOR PAGE
            $count = fgets($file);         //  2. GET THE CURRENT COUNT
            fclose($file);                 //  3. CLOSE THE FILE
            $file = fopen($ucFile, "w");   //  4. RE-OPEN FILE AND CLEAR IT
            fputs($file, $count+1);        //  5. REPLACE WITH CURRENT COUNT+1
        }
        if (!file_exists($ucFile)){        // IF THIS IS THE FIRST TIME TODAY...
            $file = fopen($ucFile, "w");   //  1. CREATE A COUNTER FOR THIS PAGE
            fputs($file, "1");             //  2. PUT 1 AS THE CURRENT COUNT
        }

        $works = setcookie($page, "Today is ".$today, $totalSecondsRemaining);
            // SET A COOKIE INDICATING THAT THIS PAGE HAS BEEN
            // VISITED ALREADY BY THIS GUEST.
    }


    // REFRESH COUNTER...
    if (file_exists($rcFile)){             // IF PAGE HAS BEEN COUNTED...
        $file = fopen($rcFile, "r+");      //  (REPEAT STEPS ABOVE, 1-5)
        $count = fgets($file);
        fclose($file);
        $file = fopen($rcFile, "w");
        fputs($file, $count+1);
    }
    if (!file_exists($rcFile)){
        $file = fopen($rcFile, "w");
        fputs($file, "1");
    }

    // AGAIN, NOT PART OF THE ORIGINAL SCRIPT.
    ob_end_flush();

    // ALWAYS RETURNS TRUE...
    echo "<!-- $works -->";
?>

我已尽我所能使该脚本再次运行。据我所知,我从未更改过代码中的任何内容;它只是有一天停止工作。

所以,到目前为止我已经检查过的是:

我也试过以下方法:

setcookie($page, "Today is ".$today, $totalSecondsRemaining);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/");
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "");

setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "mywebsite.com");
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", ".mywebsite.com");
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "*.mywebsite.com");
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "www.mywebsite.com");

setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "mywebsite.com", 0);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", ".mywebsite.com", 0);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "*.mywebsite.com", 0);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "www.mywebsite.com", 0);

setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "mywebsite.com", false);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", ".mywebsite.com", false);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "*.mywebsite.com", false);
setcookie($page, "Today is ".$today, $totalSecondsRemaining, "/", "www.mywebsite.com", false);

我将问题隔离到 PHP setcookie() 函数。非常非常感谢任何帮助。

P.S.

诚然,我确信将这些信息存储在 MySQL 数据库中会更好,但一旦我解决了这个问题,我就会继续努力。

I know the cookie expiry date is set in the future. I know the expiry date is NOT larger than PHP's integer max-size PHP Integer maximum value is about 32 bits, mine is no more than 5 characters

呃,cookie的过期时间不应该是从epoch开始的秒数吗?一个 5 位数的到期日应该是 1970 年 1 月 2 日早些时候,所以我认为您的到期日不可能既不超过五个字符,也不可能在未来。

http://php.net/manual/en/function.setcookie.php:

This is a Unix timestamp so is in number of seconds since the epoch. In other words, you'll most likely set this with the time() function plus the number of seconds before you want it to expire

<?php
setcookie("hiworld", "true", time()+300);
?>
Hi, world!


curl -v danf.us/t.php
* Adding handle: conn: 0x7ff05180d000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7ff05180d000) send_pipe: 1, recv_pipe: 0
* About to connect() to danf.us port 80 (#0)
*   Trying 66.191.143.117...
* Connected to danf.us (66.191.143.117) port 80 (#0)
> GET /t.php HTTP/1.1
> User-Agent: curl/7.30.0
> Host: danf.us
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx/1.0.10 is not blacklisted
< Server: nginx/1.0.10
< Date: Fri, 02 Jan 2015 22:31:19 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=20
< X-Powered-By: PHP/5.3.13-pl0-gentoo
< Set-Cookie: hiworld=true; expires=Fri, 02-Jan-2015 22:36:19 GMT
<
Hi, world!
* Connection #0 to host danf.us left intact