使用PHP访问没有数据库的计数器

Bac*_*ash 7 php counter

我有一个网页,我想跟踪没有使用数据库访问它的次数.

我考虑过XML,每次用户访问页面时都会更新文件:

<?xml version='1.0' encoding='utf-8'?>
<counter>8</counter>
Run Code Online (Sandbox Code Playgroud)

然后我认为在一个单独的文件中声明一个PHP计数器然后每次用户访问该页面时更新它都是一个更好的主意.

counter.php

<?php
    $counter = 0;
?>
Run Code Online (Sandbox Code Playgroud)

update_counter.php:

<?php
    include "counter.php";
    $counter += 1;
    $var = "<?php\n\t\$counter = $counter;\n?>";
    file_put_contents('counter.php', $var);
?>
Run Code Online (Sandbox Code Playgroud)

这样,每次update_counter.php访问时,counter.php文件中的变量都会增加.

无论如何,我注意到如果counter.php文件有$counter = 5,并且update_counter.php文件被同时访问的1000个用户访问,则文件同时被读取1000次(因此5在所有请求中读取该值)counter.php文件将被更新有价值5+1 (=6)而不是1005.

有没有办法让它在不使用数据库的情况下工作?

cmo*_*sey 6

您可以使用flock()哪个将锁定该文件,以便其他进程不写入该文件.

编辑:更新以使用fread()而不是include()

$fp = fopen("counter.txt", "r+");

while(!flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    // waiting to lock the file
}

$counter = intval(fread($fp, filesize("counter.txt")));
$counter++;

ftruncate($fp, 0);      // truncate file
fwrite($fp, $counter);  // set your data
fflush($fp);            // flush output before releasing the lock
flock($fp, LOCK_UN);    // release the lock

fclose($fp);
Run Code Online (Sandbox Code Playgroud)

  • 这似乎有效,除了'while-else`语法;) (2认同)
  • 您必须在 ftruncate() 之后使用 rewind()。所以你的代码目前无法工作。 (2认同)

ami*_*iio 6

<?php 

   /** 
   * Create an empty text file called counterlog.txt and  
   * upload to the same directory as the page you want to  
   * count hits for. 
    *  
       * Add this line of code on your page: 
   * <?php include "text_file_hit_counter.php"; ?> 
       */ 

  // Open the file for reading 
    $fp = fopen("counterlog.txt", "r"); 

     // Get the existing count 
       $count = fread($fp, 1024); 

     // Close the file 
   fclose($fp); 

    // Add 1 to the existing count 
       $count = $count + 1; 

      // Display the number of hits 
     // If you don't want to display it, comment out this line 
     echo "<p>Page views:" . $count . "</p>"; 

      // Reopen the file and erase the contents 
       $fp = fopen("counterlog.txt", "w"); 

                 fwrite($fp, $count); 

     // Close the file 
     fclose($fp); 

 ?> 
Run Code Online (Sandbox Code Playgroud)