php 我如何计算我网站的唯一身份访问者?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18799808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 18:14:36  来源:igfitidea点击:

How do I count unique visitors to my site?

phpmysqlcountingvisitor-statistic

提问by Nirav

I am making a visitor counting system for user posts to show the most viewed posts on homepage. I have a visitor counting system now but all it registers a view at every page refresh. I cannot use Google Analytics.

我正在为用户帖子制作一个访客计数系统,以显示主页上查看次数最多的帖子。我现在有一个访客计数系统,但它在每次页面刷新时都会注册一个视图。我无法使用 Google Analytics。

What I need is a visitor counter which only counts the unique visitors. In my case, unique means one person can only view a post in a day? Even a week might work, I think. Can you write that php code in here? You can give me a link to some good tutorials too if you like too.

我需要的是一个访客计数器,它只计算独立访客。就我而言,唯一意味着一个人一天只能查看一个帖子?我想,即使是一周也可能奏效。你能在这里写那个php代码吗?如果你也喜欢,你也可以给我一些好的教程的链接。

This is what the code needs to do (or equivalent):

这是代码需要做的(或等效的):

  1. Once the page loads, check if the visitor is new or old(I have no idea how to do it .. )
  2. If he is old, ignore him
  3. If he is new, in mysql, views = views + 1
  1. 页面加载后,检查访问者是新访问者还是旧访问者(我不知道该怎么做..)
  2. 如果他老了,忽略他
  3. 如果他是新手,在mysql中,views = views + 1

采纳答案by Mihai

http://coursesweb.net/php-mysql/register-show-online-users-visitors_t

http://coursesweb.net/php-mysql/register-show-online-users-visitors_t

Here is a nice tutorial ,is what you need.

这是一个很好的教程,正是你需要的。

Register and show online users and visitors

注册并显示在线用户和访问者

Count Online users and visitors using a MySQL table In this tutorial you can learn how to register, to count, and display in your webpage the number of online users and visitors. The principle is this: each user / visitor is registered in a text file or database. Every time a page of the website is accessed, the php script deletes all records older than a certain time (eg 2 minutes), adds the current user / visitor and takes the number of records left to display.

使用 MySQL 表计算在线用户和访问者 在本教程中,您可以学习如何注册、计算和在您的网页中显示在线用户和访问者的数量。原理是这样的:每个用户/访问者都注册在一个文本文件或数据库中。每次访问网站页面时,php 脚本都会删除所有超过特定时间(例如 2 分钟)的记录,添加当前用户/访问者并获取剩余的记录数以显示。

You can store the online users and visitors in a file on the server, or in a MySQL table. In this case, I think that using a text file to add and read the records is faster than storing them into a MySQL table, which requires more requests.

您可以将在线用户和访问者存储在服务器上的文件中,或存储在 MySQL 表中。在这种情况下,我认为使用文本文件添加和读取记录比将它们存储到需要更多请求的 MySQL 表中更快。

First it's presented the method with recording in a text file on the server, than the method with MySQL table.

首先介绍在服务器上的文本文件中记录的方法,而不是使用 MySQL 表的方法。

To download the files with the scripts presented in this tutorial, click -> Count Online Users and Visitors.

要下载包含本教程中提供的脚本的文件,请单击 -> 计算在线用户和访问者。

? Both scripts can be included in ".php" files (with include()), or in ".html" files (with ), as you can see in the examples presented at the bottom of this page; but the server must run PHP. Storing online users and visitors in a text file

? 这两个脚本都可以包含在“ .php”文件中(使用 include()),或包含在“.html”文件中(使用 ),如您在本页底部提供的示例中所见;但服务器必须运行 PHP。将在线用户和访问者存储在文本文件中

To add records in a file on the server with PHP you must set CHMOD 0766 (or CHMOD 0777) permissions to that file, so the PHP can write data in it.

要使用 PHP 在服务器上的文件中添加记录,您必须为该文件设置 CHMOD 0766(或 CHMOD 0777)权限,以便 PHP 可以在其中写入数据。

1-Create a text file on your server (for example, named "userson.txt") and give it CHMOD 0777 permissions (in your FTP application, right click on that file, choose Properties, then select Read, Write, and Execute options). 2-Create a PHP file (named "usersontxt.php") having the code below, then copy this php file in the same directory as "userson.txt". The code for usersontxt.php

1-在您的服务器上创建一个文本文件(例如,名为“userson.txt”)并为其授予 CHMOD 0777 权限(在您的 FTP 应用程序中,右键单击该文件,选择“属性”,然后选择“读取”、“写入”和“执行”选项)。2-创建一个包含以下代码的 PHP 文件(名为“usersontxt.php”),然后将此 php 文件复制到与“userson.txt”相同的目录中。userontxt.php 的代码

<?php
// Script Online Users and Visitors - http://coursesweb.net/php-mysql/
if(!isset($_SESSION)) session_start();        // start Session, if not already started

$filetxt = 'userson.txt';  // the file in which the online users /visitors are stored
$timeon = 120;             // number of secconds to keep a user online
$sep = '^^';               // characters used to separate the user name and date-time
$vst_id = '-vst-';        // an identifier to know that it is a visitor, not logged user

/*
 If you have an user registration script,
 replace $_SESSION['nume'] with the variable in which the user name is stored.
 You can get a free registration script from:  http://coursesweb.net/php-mysql/register-login-script-users-online_s2
*/

// get the user name if it is logged, or the visitors IP (and add the identifier)

    $uvon = isset($_SESSION['nume']) ? $_SESSION['nume'] : $_SERVER['SERVER_ADDR']. $vst_id;

$rgxvst = '/^([0-9\.]*)'. $vst_id. '/i';         // regexp to recognize the line with visitors
$nrvst = 0;                                       // to store the number of visitors

// sets the row with the current user /visitor that must be added in $filetxt (and current timestamp)

    $addrow[] = $uvon. $sep. time();

// check if the file from $filetxt exists and is writable

    if(is_writable($filetxt)) {
      // get into an array the lines added in $filetxt
      $ar_rows = file($filetxt, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
      $nrrows = count($ar_rows);

            // number of rows

  // if there is at least one line, parse the $ar_rows array

      if($nrrows>0) {
        for($i=0; $i<$nrrows; $i++) {
          // get each line and separate the user /visitor and the timestamp
          $ar_line = explode($sep, $ar_rows[$i]);
      // add in $addrow array the records in last $timeon seconds
          if($ar_line[0]!=$uvon && (intval($ar_line[1])+$timeon)>=time()) {
            $addrow[] = $ar_rows[$i];
          }
        }
      }
    }

$nruvon = count($addrow);                   // total online
$usron = '';                                    // to store the name of logged users
// traverse $addrow to get the number of visitors and users
for($i=0; $i<$nruvon; $i++) {
 if(preg_match($rgxvst, $addrow[$i])) $nrvst++;       // increment the visitors
 else {
   // gets and stores the user's name
   $ar_usron = explode($sep, $addrow[$i]);
   $usron .= '<br/> - <i>'. $ar_usron[0]. '</i>';
 }
}
$nrusr = $nruvon - $nrvst;              // gets the users (total - visitors)

// the HTML code with data to be displayed
$reout = '<div id="uvon"><h4>Online: '. $nruvon. '</h4>Visitors: '. $nrvst. '<br/>Users: '. $nrusr. $usron. '</div>';

// write data in $filetxt
if(!file_put_contents($filetxt, implode("\n", $addrow))) $reout = 'Error: Recording file not exists, or is not writable';

// if access from <script>, with GET 'uvon=showon', adds the string to return into a JS statement
// in this way the script can also be included in .html files
if(isset($_GET['uvon']) && $_GET['uvon']=='showon') $reout = "document.write('$reout');";

echo $reout;             // output /display the result
?>

3-If you want to include the script above in a ".php" file, add the following code in the place you want to show the number of online users and visitors:

3-如果要将上述脚本包含在“.php”文件中,请在要显示在线用户和访问者数量的位置添加以下代码:

4-To show the number of online visitors /users in a ".html" file, use this code:

4-要在“.html”文件中显示在线访问者/用户的数量,请使用以下代码:

<script type="text/javascript" src="usersontxt.php?uvon=showon"></script>

This script (and the other presented below) works with $_SESSION. At the beginning of the PHP file in which you use it, you must add: session_start();. Count Online users and visitors using a MySQL table

此脚本(以及下面介绍的另一个)与 $_SESSION 一起使用。在您使用它的 PHP 文件的开头,您必须添加:session_start();。使用 MySQL 表计算在线用户和访问者

To register, count and show the number of online visitors and users in a MySQL table, require to perform three SQL queries: Delete the records older than a certain time. Insert a row with the new user /visitor, or, if it is already inserted, Update the timestamp in its column. Select the remaining rows. Here's the code for a script that uses a MySQL table (named "userson") to store and display the Online Users and Visitors.

要在一个 MySQL 表中注册、统计和显示在线访问者和用户的数量,需要执行三个 SQL 查询: 删除超过一定时间的记录。插入包含新用户 /visitor 的行,或者,如果已插入,请更新其列中的时间戳。选择剩余的行。这是使用 MySQL 表(名为“userson”)存储和显示在线用户和访问者的脚本的代码。

1-First we create the "userson" table, with 2 columns (uvon, dt). In the "uvon" column is stored the name of the user (if logged in) or the visitor's IP. In the "dt" column is stored a number with the timestamp (Unix time) when the page is accessed. - Add the following code in a php file (for example, named "create_userson.php"): The code for create_userson.php

1-首先我们创建“userson”表,有 2 列(uvon,dt)。在“uvon”列中存储用户名(如果已登录)或访问者的 IP。在“dt”列中存储了一个带有访问页面时的时间戳(Unix 时间)的数字。- 在 php 文件中添加以下代码(例如,名为“create_userson.php”): create_userson.php 的代码

<?php
header('Content-type: text/html; charset=utf-8');

// HERE add your data for connecting to MySQ database
$host = 'localhost';           // MySQL server address
$user = 'root';                // User name
$pass = 'password';            // User`s password
$dbname = 'database';          // Database name

// connect to the MySQL server
$conn = new mysqli($host, $user, $pass, $dbname);

// check connection
if (mysqli_connect_errno()) exit('Connect failed: '. mysqli_connect_error());

// sql query for CREATE "userson" TABLE
$sql = "CREATE TABLE `userson` (
 `uvon` VARCHAR(32) PRIMARY KEY,
 `dt` INT(10) UNSIGNED NOT NULL
 ) CHARACTER SET utf8 COLLATE utf8_general_ci"; 

// Performs the $sql query on the server to create the table
if ($conn->query($sql) === TRUE) echo 'Table "userson" successfully created';
else echo 'Error: '. $conn->error;

$conn->close();
?>

2. - Now we create the script that Inserts, Deletes, and Selects data in the "userson" table (For explanations about the code, see the comments in script).
- Add the code below in another php file (named "usersmysql.php"):
In both file you must add your personal data for connecting to MySQL database, in the variables: $host, $user, $pass, and $dbname .
The code for usersmysql.php

<?php
// Script Online Users and Visitors - coursesweb.net/php-mysql/
if(!isset($_SESSION)) session_start();         // start Session, if not already started

// HERE add your data for connecting to MySQ database
$host = 'localhost';           // MySQL server address
$user = 'root';                // User name
$pass = 'password';            // User`s password
$dbname = 'database';          // Database name

/*
 If you have an user registration script,
 replace $_SESSION['nume'] with the variable in which the user name is stored.
 You can get a free registration script from:  http://coursesweb.net/php-mysql/register-login-script-users-online_s2
*/

// get the user name if it is logged, or the visitors IP (and add the identifier)
$vst_id = '-vst-';         // an identifier to know that it is a visitor, not logged user
$uvon = isset($_SESSION['nume']) ? $_SESSION['nume'] : $_SERVER['SERVER_ADDR']. $vst_id;

$rgxvst = '/^([0-9\.]*)'. $vst_id. '/i';         // regexp to recognize the rows with visitors
$dt = time();                                    // current timestamp
$timeon = 120;             // number of secconds to keep a user online
$nrvst = 0;                                     // to store the number of visitors
$nrusr = 0;                                     // to store the number of usersrs
$usron = '';                                    // to store the name of logged users

// connect to the MySQL server
$conn = new mysqli($host, $user, $pass, $dbname);

// Define and execute the Delete, Insert/Update, and Select queries
$sqldel = "DELETE FROM `userson` WHERE `dt`<". ($dt - $timeon);
$sqliu = "INSERT INTO `userson` (`uvon`, `dt`) VALUES ('$uvon', $dt) ON DUPLICATE KEY UPDATE `dt`=$dt";
$sqlsel = "SELECT * FROM `userson`";

// Execute each query
if(!$conn->query($sqldel)) echo 'Error: '. $conn->error;
if(!$conn->query($sqliu)) echo 'Error: '. $conn->error;
$result = $conn->query($sqlsel);

// if the $result contains at least one row
if ($result->num_rows > 0) {
  // traverse the sets of results and set the number of online visitors and users ($nrvst, $nrusr)
  while($row = $result->fetch_assoc()) {
    if(preg_match($rgxvst, $row['uvon'])) $nrvst++;       // increment the visitors
    else {
      $nrusr++;                   // increment the users
      $usron .= '<br/> - <i>'.$row['uvon']. '</i>';          // stores the user's name
    }
  }
}

$conn->close();                  // close the MySQL connection

// the HTML code with data to be displayed
$reout = '<div id="uvon"><h4>Online: '. ($nrusr+$nrvst). '</h4>Visitors: '. $nrvst. '<br/>Users: '. $nrusr. $usron. '</div>';

// if access from <script>, with GET 'uvon=showon', adds the string to return into a JS statement
// in this way the script can also be included in .html files
if(isset($_GET['uvon']) && $_GET['uvon']=='showon') $reout = "document.write('$reout');";

echo $reout;             // output /display the result
?>
  1. After you have created these two php files on your server, run the "create_userson.php" on your browser to create the "userson" table.
  2. Include the "usersmysql.php" file in the php file in which you want to display the number of online users and visitors.
  1. 在服务器上创建这两个 php 文件后,在浏览器上运行“create_userson.php”以创建“userson”表。
  2. 在要显示在线用户和访问者数量的 php 文件中包含“usersmysql.php”文件。
  1. Or, if you want to insert it in a ".html" file, add this code:
  1. 或者,如果要将其插入“.html”文件中,请添加以下代码:

Examples using these scripts

使用这些脚本的示例

? Including the "usersontxt.php" in a php file:

? 在 php 文件中包含“usersontxt.php”:

反制在线用户和访客

? Including the "usersmysql.php" in a html file: Counter Online Users and Visitors

? 在 html 文件中包含“usersmysql.php”:计数器在线用户和访问者

Both scripts (with storing data in a text file on the server, or into a MySQL table) will display a result like this: Online: 5

这两个脚本(将数据存储在服务器上的文本文件或 MySQL 表中)将显示如下结果: Online: 5

Visitors: 3 Users: 2 - MarPlo - Marius

访客:3 用户:2 - MarPlo - Marius

回答by Jite

Unique views is always a hard nut to crack. Checking the IP might work, but an IP can be shared by more than one user. A cookie could be a viable option, but a cookie can expire or be modified by the client.

独特的观点始终是一个难以破解的难题。检查 IP 可能有效,但一个 IP 可以由多个用户共享。cookie 可能是一个可行的选项,但 cookie 可能会过期或被客户端修改。

In your case, it don't seem to be a big issue if the cookie is modified tho, so i would recommend using a cookie in a case like this. When the page is loaded, check if there is a cookie, if there is not, create one and add a +1 to views. If it is set, don't do the +1.

在你的情况下,如果 cookie 被修改,这似乎不是一个大问题,所以我建议在这种情况下使用 cookie。当页面加载时,检查是否有cookie,如果没有,创建一个并为视图添加+1。如果设置了,不要做+1。

Set the cookies expiration date to whatever you want it to be, week or day if that's what you want, and it will expire after that time. After expiration, it will be a unique user again!

将 cookie 的到期日期设置为您想要的任何值,一周或一天,如果这是您想要的,它将在该时间之后到期。到期后,将再次成为唯一用户!



Edit:
Thought it might be a good idea to add this notice here...
Since around the end of 2016 a IP address (static or dynamic) is seen as personal data in the EU.
That means that you are only allowed to store a IP address with a good reason (and I'm not sure if tracking views is a good reason). So if you intend to store the IP address of visitors, I would recommend hashing or encrypting it with a algorithm which can not be reversed, to make sure that you are not breaching any law (especially after the GDPR laws have been implemented).

编辑:
认为在此处添加此通知可能是个好主意...
自 2016 年底左右以来,IP 地址(静态或动态)在欧盟被视为个人数据。
这意味着您只能在有充分理由的情况下存储 IP 地址(我不确定跟踪视图是否是充分理由)。因此,如果您打算存储访问者的 IP 地址,我建议您使用无法逆转的算法对其进行散列或加密,以确保您没有违反任何法律(尤其是在实施 GDPR 法律之后)。

回答by Broccoli

I have edited the "Best answer" code, though I found a useful thing that was missing. This is will also track the ip of a user if they are using a Proxy or simply if the server has nginx installed as a proxy reverser.

我已经编辑了“最佳答案”代码,但我发现缺少一个有用的东西。如果用户使用代理,或者如果服务器安装了 nginx 作为代理反向器,这也将跟踪用户的 ip。

I added this code to his script at the top of the function:

我将此代码添加到函数顶部的脚本中:

function getRealIpAddr()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
$adresseip = getRealIpAddr();

Afther that I edited his code.

之后我编辑了他的代码。

Find the line that says the following:

找到以下内容的行:

// get the user name if it is logged, or the visitors IP (and add the identifier)

    $uvon = isset($_SESSION['nume']) ? $_SESSION['nume'] : $_SERVER['SERVER_ADDR']. $vst_id;

and replace it with this:

并将其替换为:

$uvon = isset($_SESSION['nume']) ? $_SESSION['nume'] : $adresseip. $vst_id;

This will work.

这将起作用。

Here is the full code if anything happens:

如果发生任何事情,这是完整的代码:

<?php

function getRealIpAddr()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
$adresseip = getRealIpAddr();

// Script Online Users and Visitors - http://coursesweb.net/php-mysql/
if(!isset($_SESSION)) session_start();        // start Session, if not already started

$filetxt = 'userson.txt';  // the file in which the online users /visitors are stored
$timeon = 120;             // number of secconds to keep a user online
$sep = '^^';               // characters used to separate the user name and date-time
$vst_id = '-vst-';        // an identifier to know that it is a visitor, not logged user

/*
 If you have an user registration script,
 replace $_SESSION['nume'] with the variable in which the user name is stored.
 You can get a free registration script from:  http://coursesweb.net/php-mysql/register-login-script-users-online_s2
*/

// get the user name if it is logged, or the visitors IP (and add the identifier)

    $uvon = isset($_SESSION['nume']) ? $_SESSION['nume'] : $_SERVER['SERVER_ADDR']. $vst_id;

$rgxvst = '/^([0-9\.]*)'. $vst_id. '/i';         // regexp to recognize the line with visitors
$nrvst = 0;                                       // to store the number of visitors

// sets the row with the current user /visitor that must be added in $filetxt (and current timestamp)

    $addrow[] = $uvon. $sep. time();

// check if the file from $filetxt exists and is writable

    if(is_writable($filetxt)) {
      // get into an array the lines added in $filetxt
      $ar_rows = file($filetxt, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
      $nrrows = count($ar_rows);

            // number of rows

  // if there is at least one line, parse the $ar_rows array

      if($nrrows>0) {
        for($i=0; $i<$nrrows; $i++) {
          // get each line and separate the user /visitor and the timestamp
          $ar_line = explode($sep, $ar_rows[$i]);
      // add in $addrow array the records in last $timeon seconds
          if($ar_line[0]!=$uvon && (intval($ar_line[1])+$timeon)>=time()) {
            $addrow[] = $ar_rows[$i];
          }
        }
      }
    }

$nruvon = count($addrow);                   // total online
$usron = '';                                    // to store the name of logged users
// traverse $addrow to get the number of visitors and users
for($i=0; $i<$nruvon; $i++) {
 if(preg_match($rgxvst, $addrow[$i])) $nrvst++;       // increment the visitors
 else {
   // gets and stores the user's name
   $ar_usron = explode($sep, $addrow[$i]);
   $usron .= '<br/> - <i>'. $ar_usron[0]. '</i>';
 }
}
$nrusr = $nruvon - $nrvst;              // gets the users (total - visitors)

// the HTML code with data to be displayed
$reout = '<div id="uvon"><h4>Online: '. $nruvon. '</h4>Visitors: '. $nrvst. '<br/>Users: '. $nrusr. $usron. '</div>';

// write data in $filetxt
if(!file_put_contents($filetxt, implode("\n", $addrow))) $reout = 'Error: Recording file not exists, or is not writable';

// if access from <script>, with GET 'uvon=showon', adds the string to return into a JS statement
// in this way the script can also be included in .html files
if(isset($_GET['uvon']) && $_GET['uvon']=='showon') $reout = "document.write('$reout');";

echo $reout;             // output /display the result

Haven't tested this on the Sql script yet.

还没有在 Sql 脚本上测试过这个。

回答by Alireza Fallah

for finding out that user is new or old , Get user IP .

为了找出用户是新用户还是旧用户,获取用户IP。

create a table for IPs and their visits timestamp .

为 IP 及其访问时间戳创建一个表。

check IF IP does not existsOR time()-saved_timestamp > 60*60*24(for 1 day) ,edit the IP's timestamp to time()(means now) and increase your view one .

检查 IF IP does not existOR time()-saved_timestamp > 60*60*24(for 1 day) ,将 IP 的时间戳编辑为time()(表示现在)并增加您的视图一。

else , do nothing .

否则,什么都不做。

FYI: user IP is stored in $_SERVER['REMOTE_ADDR']variable

仅供参考:用户 IP 存储在$_SERVER['REMOTE_ADDR']变量中

回答by asif

$user_ip=$_SERVER['REMOTE_ADDR'];

$check_ip = mysql_query("select userip from pageview where page='yourpage'  and userip='$user_ip'");
if(mysql_num_rows($check_ip)>=1)
{

}
else
{
  $insertview = mysql_query("insert into pageview values('','yourpage','$user_ip')");

  $updateview = mysql_query("update totalview set totalvisit = totalvisit+1 where page='yourpage' ");
}

code from talkerscode official tutorial if you have any problem http://talkerscode.com/webtricks/create-a-simple-pageviews-counter-using-php-and-mysql.php

如果你有任何问题,来自talkerscode官方教程的代码http://talkerscode.com/webtricks/create-a-simple-pageviews-counter-using-php-and-mysql.php