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

标签 php setcookie

我真的需要一些帮助。我编写了这个脚本来跟踪我的网站流量。我使用 cookie 来帮助服务器了解客户端当天是否访问过某个页面一次,这使我能够通过两 (2) 个计数器/类别来跟踪访问者:独特的点击和“刷新”点击。

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

每个页面都会调用脚本counter.php。一切似乎都工作正常,但我的两个计数器继续读取相同的数字,就好像每次点击都是唯一的。当我看到这两组数字时我就知道出了问题,并通过刷新几次索引页来确认。这意味着 cookie 没有被设置。 counter.php 中的 PHP 脚本测试 cookie 以查看它是否已设置。我还检查了浏览器设置中的 cookie,但没有显示 cookie。我多次刷新每个页面并重新检查 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 -->";
?>

我已经尝试了所有我能想到的方法来让这个脚本再次运行。据我所知,我从未更改过代码中的任何内容;它有一天停止工作了。

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

  • 我知道在发送 header 之前没有NO输出。
  • 我知道 PHP 认为 cookie 已被设置,因为 setcookie() 返回 true
  • 我知道 Cookie 的到期日期是在将来设置的。
  • 我知道到期日期大于 PHP 的整数最大大小
    • PHP Integer 最大值约为 32 位,我的不超过 5 个字符
  • 我知道 www.example.comexample.com 都不会改变脚本的行为

我还尝试了以下方法:

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() 函数。非常非常非常感谢任何帮助。

附注

诚然,我确信将这些信息存储在 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 的过期时间不应该是自纪元以来的秒数吗? 5 位数的到期日期将是 1970 年 1 月 2 日早些时候,因此我认为您的到期日期不可能既是 5 个字符或更少,又是在未来。

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

关于PHP 的 setcookie() 函数不起作用。怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27749245/

相关文章:

PHP 生成的元素忽略 div - Wordpress

php - 有没有办法测试字符串是否 gzdeflated?

php - 解析 HTML 的 XPath 表达式 - 部分通配符表达式

javascript - 如果未选择任何内容,PHP setcookie 不显示

php - 将 $_SERVER ['REQUEST_URI' ] 保存为 cookie 时的 float 后缀

php - 动态页面的 Apache mod 重写

php - 如何使用密码保护目录但仍授予用户访问权限

php - 如何从具有不同 URL 的网页访问 cookie 信息

angularjs - 如何使用Angular cookie存储(和检索)cookie数组

php - PHP 中的单元测试 cookie