duanjia1870 2015-01-02 22:14 采纳率: 0%
浏览 230
已采纳

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

I really need some help here. I wrote this script to track my website's traffic. I was using cookies to help the server know when a client has visited a page once already for the day, which allowed me to track visitors by two (2) counters/categories: UNIQUE hits and "REFRESH" hits.

I store the information in directories named by date. For example, the file located at www.example.com/counter/unique/2015/12/31/about would store a number like 62, which would mean I got 62 unique hits to the about.php page on December 31st, 2015.

Each page calls the script counter.php. Everything seems to work fine, but both of my counters continue to read the same number, as if every hit is unique. I knew something was wrong when I saw the two sets of numbers, and I confirmed it by refreshing the index page several times. What it means is that the cookies are not being set. The PHP script in counter.php tests for the cookie to see if it has been set. I have been also checking the cookies from my browser settings and it shows no cookies. I refresh each page several times and re-check for the cookies several times, but still no luck!

What in the world is going on here?!? It was working before!

The following shows how each page calls the counter.php script:

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

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

The following is my PHP code called 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 -->";
?>

I have tried everything I can think of to get this script working again. To the best of my knowledge, I never changed anything in the code; it just stopped working one day.

So, what I've already checked so far is:

  • I know there is NO output before the headers are sent.
  • I know that PHP thinks the cookie is being set, because setcookie() returns true
  • 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
  • I know that neither www.example.com nor simply example.com change the script's behavior

I have also tried the following:

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);

I isolated the problem to the PHP setcookie() function. Any help is really, really, greatly appreciated.

P.S.

Admittedly, I'm sure that it would be better to store this information in a MySQL Database, but I'll work on that once I get this problem fixed.

  • 写回答

1条回答 默认 最新

  • dongshadu4498 2015-01-02 22:28
    关注

    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

    Uh, shouldn't the expiry time of a cookie be the number of seconds since epoch? A 5 digit expiry date would be early January 2nd, 1970, so I don't think it's possible that your expiry date is both five characters or less, and also in the future.

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化