I want to track IP addresses of visitors to my blog. I don't know which blog I'm going to use, I'll use whichever one will work (i hear blogger doesn't work with php).
Also, once I make the blog and set up the IP tracker, where will I go to find the IP addresses of my visitors? Thanks in advance!
You can check the access log of your http server. This should give you a list of client requests.
If your looking for a php solution, you can use the following to get the ip address of the client:
$_SERVER['REMOTE_ADDR'];
You'll need to write a quick logging script to store these
$logFile = 'iplog.log';
if(!file_exists($logFile)) touch($logFile);
if(is_writable($logFile)) {
$fh = fopen($logFile, 'a');
if($fh) {
$line = $_SERVER['REMOTE_ADDR']."\n";
fwrite($fh, $line, strlen($line));
fclose($fh);
}
}
u can register at this site.. this site good tools for tracking ips.. http://fcounter.com
If later on you would like to use those IPs as for example in admin area of your blog, then IMHO it is better to store them in database. Later on you can cache them, but it is optional.
In WordPress (which is by the way very elastic blog system) database tables have wp_ prefix by default. So you could do something like that.
CREATE TABLE IF NOT EXISTS wp_ip_tracking (
id INT NOT NULL AUTO_INCREMENT,
ip VARCHAR(15) NOT NULL,
last_activity TIMESTAMP NOT NULL,
PRIMARY KEY(id),
UNIQUE(ip)
);
Then you could do some function which will be called, when member does pretty much anything. Depends on what you need.
function trackIP($ip) {
// Check if IP exists
$query1 = "SELECT id FROM wp_ip_tracking WHERE ip = '{$ip}'";
// Insert new record with given IP
$query2 = "INSERT INTO wp_ip_tracking(id, ip, last_activity) VALUES(NULL, '{$ip}', NOW())";
// Update record for specified IP
$query3 = "UPDATE wp_ip_tracking SET last_activity = NOW() WHERE ip = '{$ip}'";
if(mysql_num_rows(mysql_query($query1)) == 0) {
mysql_query($query2);
} else {
mysql_query($query3);
}
}
I think that those two should help you with your problem. Again it is only IMHO.
Related
I'm building a site that lets users anonymously post messages to a board and rate other messages. Because it's anonymous and doesn't use any kind of user id, when someone clicks to vote up or down on a post, I need to store that post_id and their IP address so they can't vote again.
Here's the system I have in place, it does not work and I don't know why:
mysqli_autocommit($connection, TRUE);
mysqli_query($connection, "UPDATE $tablename SET downvotes = (downvotes + 1) WHERE id = $post_id AND NOT EXISTS (SELECT 1 FROM $table2name WHERE ip = $ip_usr AND post_id = $post_id");
if(mysqli_affected_rows($connection) > 0) {
$insert = mysqli_query($connection, "INSERT INTO $table2name VALUES($post_id, $ip_usr)");
$insert ?
mysqli_commit($connection):
mysqli_rollback($connection);
} else {
mysqli_rollback($connection);
}
I received a tip that instead of using mysqli_autocommit() I should use mysqli_begin_transaction(), however I am using PHP version 5.2 and that function doesn't exist yet, and I have no way of upgrading my PHP version.
The gist of what I'm trying to do is when someone tries to vote on a post, if they haven't voted yet, their vote is made and their IP and that post's id are added into a table. If they have already voted, nothing happens.
Can anyone please help me? Thanks!
I have a table with a request log. In there is a column with referers. Now in order to see what domains refer the most requests I want to add a new column with the host of the referer.
That is no problem for the new entries but how do I update every row without an entry in the new row to have the host from the referer?
Is there an easy way to do this in MySQL or how di I solve it in PHP?
$oldRows = mysql_query("SELECT * FROM logs_requests WHERE host_ref = ''");
while($row = mysql_Fetch_array($oldRows))
{
$host = parse_url($row['url_ref'], PHP_URL_HOST);
mysql_query("UPDATE logs_requests SET host_ref='$host' WHERE id='{$row['id']}'");
}
This php code fetch all the rows with empty host_ref field,
then it takes the host (www.domain.com) from the url_ref (www.domain.com/page/34.html) with the parse_url function.
After that , there's an update query which updates the host field.
NOTICE: Customize this code according to your db scheme.
I am trying to create a web survey questionaire, but I don't want same people using same ip to submit it more than once within an hour time, I am using php, I assume I need to use
$_SERVER['REMOTE_ADDR'] to get the client ip and store in the session or database and then use it to compare the new ip, I am not sure if it is right and don't know how to exact implement this in php, can anyone help me with it, thanks in advance!
When survey is submitted:
/*
Tracking table structure:
`id` INT(11) unsigned NOT NULL AUTO_INCREMENT
`client_ip` VARCHAR(15) NOT NULL
`submitted_time` DATETIME NOT NULL
*/
$query = "SELECT count(`id`) AS 'count'
FROM `tracking_table`
WHERE
`client_ip` = '".mysqli_real_escape_string($link, $_SERVER['REMOTE_ADDR'])."'
AND `submitted_time` > '".date('Y-m-d H:i:s',strtotime('-1 hour'))."'
LIMIT 1";
$result = mysqli_fetch_assoc(mysqli_query($link, $query));
if ($result['count'] > 0) {
echo "You have already submitted within the last hour";
exit;
}
// process survey here
$query = "INSERT INTO `tracking_table`
(`client_ip`, `submitted_time`)
VALUES
('".mysqli_real_escape_string($link, $_SERVER['REMOTE_ADDR'])."', ".date('Y-m-d H:i:s').")";
mysqli_query($link, $query);
However, you may find that this is not a good requirement - there are many valid situations where multiple users may use the same IP address (such as, for example, student accomodation). You may be preventing valid submissions by imposing this limit.
EDIT
Here is a basic outline of how you might do this with cookies (taking into account the limitations discussed below).
Our cookie system works on a pair of values. ckv_1 will hold the timestamp at which the last survey was submitted. ckv_2 will hold a hash based on the timestamp and a salt, in an effort to stop people from screwing with the cookies. Obviously, if both cookies are deleted, we won't be able to detect it, but at least this provides some sort of validation:
function get_cookie_hash ($timestamp, $salt) {
return md5("Extra random static string; TS: $timestamp; Salt: $salt; Extra random static string.");
}
$cookieSalt = 'Th1si54rAnd0MsTr1nG!';
// If at least one of the cookies was returned, validate the request
if (!empty($_COOKIE['ckv_1']) || !empty($_COOKIE['ckv_2'])) {
$valid = FALSE;
do { // Wrapped in a do-while to allow us to break out easily
// Make sure both value are set
if (empty($_COOKIE['ckv_1']) || empty($_COOKIE['ckv_2'])) break;
// Get old timestamp as integer
$oldTS = hexdec($_COOKIE['ckv_1']);
// Make sure timestamp is more than one hour old, and the hash cookie matches it
if ($oldTS > (time() - 3600) || $_COOKIE['ckv_2'] != get_cookie_hash($oldTS, $cookieSalt)) break;
// OK if you get here
$valid = TRUE;
} while (FALSE);
if (!$valid) {
echo "Sorry - you cannot submit a survey more than once in an hour.";
exit;
}
}
// process survey here
// Set the tracking cookies after processing (but before any output!)
// We'll set them as HTTP only to help prevent XSS-type attacks
$cookieTime = time();
setcookie('ckv_1', dechex($cookieTime), 7200, '', '', FALSE, TRUE);
setcookie('ckv_2', get_cookie_hash($cookieTime, $cookieSalt), 7200, '', '', FALSE, TRUE);
Use a database to store IPs and timestamps of votes, and then when recording the vote (or better yet; when displaying the survey so you tell the user that he already voted) check the database if user's IP ($_SERVER['REMOTE_ADDR']) is already in the DB and if the timestamp is younger than one hour. If it is don't allow him to vote, otherwise do.
You can wrap your checks in a class and then use it when your action requires the functionality:
class IPChecker
{
public function storeIP($ip)
{
# save $ip with now() and context (if available)
# in your database
...
}
public function isBlocked($ip)
{
# test if $ip by now() and context (if available)
# is in your database
...
# return true / false;
}
}
$ipchecker = new IPChecker();
# on form submit:
$ip = $_SERVER['REMOTE_ADDR'];
if ($ipchecker->isBlocked($ip))
{
# blocked
...
}
else
{
# good
$ipchecker->storeIP($ip);
...
}
REMOTE_ADDR does indeed get you an IP address. But:
At many companies (especially large ones), outgoing traffic goes through proxies or firewalls, which makes the entire company—or at least entire location—appear to come from a few IP addresses. One IP address may easily be 10,000 people.
Some ISPs use transparent proxying to save on bandwidth. Often, its only transparent to the client, so an entire ISP (or at least region) will come from several IPs.
Cell phones often are assigned new IP addresses more often than every hour, and being told you've already voted when you haven't would be quite annoying.
IPv6 opens a whole new can of worms. Privacy extensions are designed to break what you're doing. They will.
So, here is a more accurate description of REMOTE_ADDR: An address that, as part of the full TCP session address (server, server port, remote address, remote port) lets you send a packet that is part of said session. It may or may not be the address of the actual client (usually isn't), may or may not match from request-to-request, and may or may not be shared by numerous other people.
Store the $_SERVER['REMOTE_ADDR'] in database table with the time stamp it last submitted the survey. The table may have two columns like IPAddress(varchar 100), TimeStamp(int). and in php code
<?php
//query the $_SERVER['REMOTE_ADDR'] in database and get timestamp, if found compare it with current time stamp, difference should be greater than an hour
if($diff > 3600)
{
print "You are not allowed to post your survey more than once in an hour"
exit;
}
//Your page code
?>
I have never coded php before and I really need this very simple script.
so let me explain what I need.
user comes to my website via affiliate link so when they finished redirecting
the url will look like this
http://website.com/lp/index.html?sub=1&customer_id=1039be6e23b4420c3e1063dc44a04d
now I have a download link on my website
On download click
check for duplicate ip address from database. if not duplicate
capture sub="" & customer_id="" from the address bar.
save to database with IP Address (this for tracking)
and redirect immediately to the download link
if the ip is not duplicated
http://dl.website.com/download/downloadpop.aspx?id={Customer_id}
if it's duplicated
http://dl.website.com/download/downloadpop.aspx?id=beenbefore
Thank you so much!
You probably want header for the redirect:
http://php.net/manual/en/function.header.php
And mysql_connect, mysql_query, etc. for DB stuff:
http://php.net/manual/en/book.mysql.php
You can extract GET params from $_GET:
http://php.net/manual/en/reserved.variables.get.php
Note that any call to header() must take place before other output (see the example on the page linked.)
This is rather broad, and impossible to answer properly without knowing any details about your database structure, but here's how the basics of this would work:
<?php
$sub = $_GET['sub'];
$customer_id = $_GET['customer_id'];
$ip = $_SERVER['REMOTE_ADDR'];
$db = mysql_connect(...) or die(mysql_error());
$quoted_sub = mysql_real_escape_string($sub);
$quoted_customer_id = mysql_real_escape_string($customer_id);
$quoted_ip = mysql_real_escape_string($ip);
$sql = "SELECT count(*) AS cnt FROM yourtable WHERE ip_address = '$quoted_id'";
$result = msyql_query($sql) or die(mysql_error());
$row = mysql_fetch_assoc($result);
if ($row['cnt'] == 0) {
$enc = urlencode($customer_id);
... IP isn't in the database, so do the insert stuff ...
header(" http://dl.website.com/download/downloadpop.aspx?id=$enc");
} else {
header("Location: http://dl.website.com/download/downloadpop.aspx?id=beenbefore");
}
exit();
First off, you can access these variables via $_GET().
Next, you INSERT them into a database using PDO.
Finally, you can redirect someone with the appropriate header():
header('Location:http://dl.website.com/download/downloadpop.aspx?id=beenbefore');
Currently I have a file called "hits.php" and on any page I want to track page hits I just use <?php include("hits.php"); ?>
How can I track unique visitors only though? My hits are false since it can be refreshed by the same person and hits go up.
Here's my source:
<?php
$hits = file_get_contents("./client/hits.txt");
$hits = $hits + 1;
$handle = fopen("./client/hits.txt", "w");
fwrite($handle, $hits);
fclose($handle);
print $hits;
?>
I don't really know how I could do cookie checking... is there a way to check IP's? Or what can I do?
Thanks StackO.
The simplest method would be cookie checking.
A better way would be to create an SQL database and assign the IP address as the primary key. Then whenever a user visits, you would insert that IP into the database.
Create a function included on all pages that checks for $_SESSION['logged'] which you can assign whatever 'flag' you want.
If $_SESSION['logged'] returns 'false' then insert their IP address into the MySQL database.
Set $_SESSION['logged'] to 'true' so you don't waste resources logging the IP multiple times.
Note: When creating the MySQL table, assign the IP address' field as the key.
<?php
session_start();
if (!$_SESSION['status']) {
$connection = mysql_connect("localhost", "user", "password");
mysql_select_db("ip_log", $connection);
$ip = $_SERVER['REMOTE_ADDR'];
mysql_query("INSERT INTO `database`.`table` (IP) VALUES ('$ip')");
mysql_close($connection);
$_SESSION['status'] = true;
}
?>
There isn't a perfect solution, but the first two methods (IP address and/or cookies) are the most reliable, and a combination might be even better.
Rather than reinventing the wheel I used an off the shelf solution. For commercial reasons I avoided Google Analytics (I don't want Google to know my web stats - their best interests are not mine). They're probably fine for non-commercial websites, or if you don't use Google for advertising. There are also dozens of alternatives. Eg I use Getclicky.com
At a basic level, you can get the client's IP address by using the PHP $_SERVER['REMOTE_ADDR'] property
Consider setting a cookie or using a session, though this can be defeated by deletion of a cookie or cookie rejection. See the PHP setcookie docs for more info.
There are other methods for browser fingerprinting - check out all the different data you could conceivably use at https://coveryourtracks.eff.org/
How about google analytics if you cant. you could do a database or create another file with the IPs in it, but it could get complicated with a flat file like that.
I found the solution of very poor quality and just a quick and dirty way of doing it.
I too was developing something similar and formulated a quick method which works without redundancy.
I needed a counter for every time someone accessed another user's profile.
Pseudo:
Create a table with viewer's name and viewee's name (daily_views table).
Check to see if exists the viewer's name with the viewee's name (on the same row).
If they do not exist, update user counter +1 (in users table).
Else do nothing.
Reset entire table values null every 24/12 hours via cron job.
This will deny the same person accessing the same user profile to add 1 to the
counter on refresh for the whole day (or 12 hours) whereas the above solution
by Glenn Nelson would indeed add 1 to the counter, but deny adding to every
user's counter at the same time.
Not only this, but if you were to logoff and log back in to the website, then
it would simply re-add to the counter in which some cases trolls and haxorz
wannabe's will exploit this (as the session is destroyed and started again).
Here are my sample tables:
users
{
user_id INT(8) auto increment, user_name varchar(32), user_counter INT(12)
};
daily_views
{
view_id INT(8) auto increment, viewer_name VARCHAR(32), viewee_name VARCHAR(32)
};
Here is sample code I've written:
<?php
session_start();
$uname = $_SESSION['username'];
$vieweepage = $_GET['name']; //gets the name of the persons page/profile via previous page/form
$connect = mysql_connect("localhost","user","password") or die("Couldn't connect; check your mysql_connect() settings");
$database = mysql_select_db("database") or die("Could not locate database!");
$query = mysql_query("SELECT user_counter from users");
$query = mysql_fetch_row($query);
$counter = $query[0];
$viewcheck = mysql_query("SELECT viewer_name from daily_views WHERE viewee_name='$vieweepage'");
$viewrow = mysql_num_rows($viewcheck);
$newcounter = $counter + 1;
if($viewrow == 0)
{
$update = mysql_query("UPDATE users SET user_counter='$newcounter' WHERE user_name='$vieweepage'");
$insert = mysql_query("INSERT into daily_views (viewer_name, viewee_name) VALUES ('$uname', '$vieweepage')");
}
?>
currently i am using remote address and session ID for visitor.i think its valid visitor because a single user can visit no of times in a days and counter not depends on refresh its only depends on new session.
You could save a timestamp to localStoage in javascript. LocalStoage isn't removed by the browser, so you should be save to check against that. I know that it isn't serverside checking, but it may be helpful anyway.