简体   繁体   English

在php中获得独特的命中数

[英]Getting unique hit count in php

I want to add a unique hit counter to my website using PHP. 我想使用PHP为我的网站添加一个独特的点击计数器。 This counter will save visitor's IP for each page in a database. 此计数器将为数据库中的每个页面保存访问者的IP。 I have a database structure like this: 我有这样的数据库结构:

Table hits with two columns: hits两列:

ip
page_url

My question is: after getting the visitor's IP in a PHP file, which is better (for performance)? 我的问题是:在PHP文件中获取访问者的IP后,哪个更好(性能)?

  1. To check if the IP address is already in the database. 检查IP地址是否已存在于数据库中。 And when not already in the database add it 当还没有在数据库中添加它
  2. Just add all visitors IPs (without duplicate check) and then get distinct IPs for relevant page to get the unique hit count? 只需添加所有访问者IP(无需重复检查),然后获取相关页面的不同IP以获得唯一的命中数?

If you are on MySQL you might want to abuse the combination of PRIMARY KEY and ON DUPLICATE KEY UPDATE: 如果您使用的是MySQL,则可能需要滥用PRIMARY KEY和ON DUPLICATE KEY UPDATE的组合:

CREATE TABLE hits (
ip VARCHAR(15),
page_url VARCHAR(200),
PRIMARY KEY (ip,page_url),
hitcount INT NOT NULL DEFAULT 0
)

Now on a page hit you do 现在在页面上点击你做

INSERT INTO hits(ip, page_url,hitcount) VALUES('$ip','$url',1)
ON DUPLICATE KEY UPDATE hitcount=hitcount+1

Why this? 为什么这个?

  • Another unique key is POISON for a write-heavy table, so avoid it. 另一个唯一的关键是POISON用于写入繁重的表,因此请避免使用它。 Really. 真。
  • INSERT ... ON DUPLICATE KEY UPDATE only locks the row once INSERT ... ON DUPLICATE KEY UPDATE仅锁定行一次

You may also want to record the timestamp of last access: 您可能还想记录上次访问的时间戳:

ALTER TABLE hits ADD COLUMN lastseen TIMESTAMP();

with the help of Eugen Rieck I made my code with time and date store. Eugen Rieck的帮助下,我用时间和日期存储我的代码。

In this code, it store user ip, count,date and time. 在此代码中,它存储用户ip,计数,日期和时间。

 $ipaddress = ''; if (getenv('HTTP_CLIENT_IP')) $ipaddress = getenv('HTTP_CLIENT_IP'); else if(getenv('HTTP_X_FORWARDED_FOR')) $ipaddress = getenv('HTTP_X_FORWARDED_FOR'); else if(getenv('HTTP_X_FORWARDED')) $ipaddress = getenv('HTTP_X_FORWARDED'); else if(getenv('HTTP_FORWARDED_FOR')) $ipaddress = getenv('HTTP_FORWARDED_FOR'); else if(getenv('HTTP_FORWARDED')) $ipaddress = getenv('HTTP_FORWARDED'); else if(getenv('REMOTE_ADDR')) $ipaddress = getenv('REMOTE_ADDR'); else $ipaddress = 'UNKNOWN'; // final ip address $time=date("Y/m/d H:i:s"); // date and time in a single variable $sql = "INSERT IGNORE INTO `ipaddress` (`id`, `ipaddress`, `count`, `time`) VALUES ('', '$ipaddress','1', '$time') ON DUPLICATE KEY UPDATE count=count+1, time='".$time."'"; // adding ip,count, date and time to table if($conn->query($sql) === false) { trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $last_inserted_id = $conn->insert_id; $affected_rows = $conn->affected_rows; } $conn->close(); 

Presuming you're comfortable with simple programming. 假设你对简单的编程感到满意。

NOT TRULY "REAL TIME" BUT ALMOST REAL TIME Highly recommend you to write out to a log with your own format to a text file (if you're not comfortable with Apache's [customlog][1] feature). 不是真正的“实时”但是几乎是实时强烈建议您使用自己的格式写入日志文本文件(如果您对Apache的[customlog][1]功能不满意)。

Then, set up a cronjob every 5 minutes, or even once every 1 minute if you want close to "live", import the text into a MySql temporary table in a big gulp with LOAD DATA INFILE and then update your visitcounts table based on GROUP BY ip. 然后,每隔5分钟设置一个cronjob,如果你想要接近“live”,甚至每1分钟设置一次cronjob,将文本导入到带有LOAD DATA INFILE的大口中的MySql临时表中,然后根据GROUP更新你的visitcounts表通过ip。

FULLY REAL TIME This can be a huge drag on your server but given that you have light traffic just create two tables in MySQL. 完全实时这可能对您的服务器造成巨大拖累,但考虑到您拥有轻量级流量,只需在MySQL中创建两个表。 One just records the article/page ID being read + IP + time (log table). 一个只记录正在读取的文章/页面ID + IP +时间(日志表)。 The other contains article/page ID and visit counts--where the counts are updated GROUP BY ip in the first table. 另一个包含文章/页面ID和访问计数 - 其中计数更新在第一个表中的GROUP BY ip。

I would use unique key on ( ip , page_url ), optionally date . 我会在( ippage_url )上使用唯一键,可选择date If the record isn't there it would be create, it would cause error otherwise (but you can easily check error code) or you could use IGNORE in INSERT statement.. 如果记录不存在则会创建,否则会导致错误(但您可以轻松检查错误代码)或者您可以在INSERT语句中使用IGNORE

It'd take only one request to the database and would be probably the fastest. 它只需要一个数据库请求,可能是最快的。 You would have also automatically guaranteed that all records will be unique and you wouldn't need to use a transaction. 您还可以自动保证所有记录都是唯一的,您不需要使用事务。

Hi john and fellow flow peeps... I'm new to programming and MYSQL, ...however the way I got round it was the following: 嗨约翰和其他流程偷看......我是编程和MYSQL的新手,...但是我绕过它的方式如下:

I use some PHP code to query the hits DB and then evaluate both columns, ip and page_url and if they evaluate to true do nothing, else ...insert/execute the code shown above by Eugene Rick... 我使用一些PHP代码来查询命中数据库然后评估列, ippage_url ,如果它们评估为true则不执行任何操作,否则...插入/执行Eugene Rick上面显示的代码...

$ip = $_SERVER['REMOTE_ADDR']; // Get IP Address.

$purl = htmlspecialchars($_GET['page_url']); // Get Page URL.

$results = $mysqli->query("select * from hits"); // Query hits table.

$row = $results->fetch_assoc(); // Fetch array and assign to $row, then evaluate with if statement.

if ($row['ip'] == $ip && $row['page_url'] == $purl) {

} else {
    $mysqli->query("insert into hits (ip,page_url,counter) values ('$ip','$purl',1) on duplicate key update counter=counter+1");
}

I'll be honest I have not checked this on more than one IP address, just mine. 老实说,我没有在多个IP地址上检查过这个,只是我的。

However it adds rows to the hits table for each URL inserted based on an unique ip (the one I'm currently using) and does not increment the hits count for any inserted URL when the page is refreshed so I assume it works... 然而,它为每个基于唯一的ip(我正在使用的那个)插入的URL添加到hits表中的行,并且当刷新页面时不会增加任何插入的URL的命中数,所以我认为它有效...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM