I've setup a PHP IP Blacklist system and it works really well.
I now want it to be able to take a reason from the txt file.
ip_blacklist.txt
1.2.4.5 , No Spamming Allowed
1.2.4.5 , No Spamming Allowed
1.2.4.5 , No Spamming Allowed
Now in PHP it get's the IP to compare it to the users IP being used, that's perfect.
But if the IP matches the IP in the txt it will redirect you to a blacklist page.
I want it to display the reason for their blacklisting.
How do I get the reason matching the IP in the txt file using PHP and then linking it to
$reason?
Like the answers above, I agree that the best way to solve this would be store the user's IP in a database, but if you still need to read a file for it, this code should do the job:
<?php
//The file you will read
$file = fopen("ip_blacklist.txt", "r") or exit("Unable to open file!");
//Where we will store each ip as we read it
$ip = "";
$parts;
while(!feof($file))
{
//Split the line and save the parts
$parts = explode(" , ", fgets($file));
$ip = $parts[0];
$reason = $parts[1];
//And here you can compare it to the client's ip
//The first one is the ip read from the file
echo $ip."<br>";
//And this is how you would get the client's ip
echo $_SERVER['REMOTE_ADDR']."<br>";
}
//Close the file
fclose($file);
?>
Note that the way to get the client's IP I used is not the best by any means (since it can be spoofed really easily). For more information about that, read here How to get Client IP address in PHP?
-Edit-
And I just noticed you simply wanted to check the IP, compare it and get the reason. In that case, change the while to:
while(!feof($file))
{
//Split the line and save the parts
$parts = explode(" , ", fgets($file));
$ip = $parts[0];
if($_SERVER['REMOTE_ADDR'] == $ip)
echo $parts[1];
}
Or you could use explode:
$myTextFileLine = "1.2.4.5 , No Spamming Allowed";
$cutted = explode(",", $myTextFileLine);
echo "Ip blacklisted: ".$cutted[0].", reason: ".$cutted[1];
Edit: Edited to include preg_match method of getting result from file instead of db. This method would do the check if the user is in the blacklist as well as get the users reason.
You could simply store the users IP in your database along with a reason. Then when the check is run, if the user is in the blacklist, query the database for their ip, and return and display the reason.
$ip = $_SERVER['REMOTE_ADDR'];
$sql = 'SELECT reason FROM blacklist WHERE ip = "' . $ip . '"';
Then run that sql against your database. Ofcourse that is a rough idea and has no protection against sql injection, so I would advise in using some form of excaping and validating that $ip is in the correct format for an ip address before running the query.
The overall process would be:
Check if user is in blacklist by comparing ip to file.
User is in blacklist.
Get reason from database by the users ip.
Display reason.
If you are just looking to do it all by file, then it would be a better of getting the file contents, finding the ip and reason and displaying the reason.
This could be done using preg_match.
$file = file_get_contents('path/to/blacklist/file');
$ip = $_SERVER['REMOTE_ADDR'];
$pattern = '#' . $ip . '\s,\s.*#';
if(preg_match($pattern, $file_contents, $matches)) {
$match = $matches[0];
$explode = explode(',', $match);
$reason = $explode[1];
echo $reason;
}
Note this is untested, but I think it would work.
Related
After almost 3 days of troubleshooting I gotta ask for advice.
A have a small imageboard with 4 images and 4 'like' buttons. Earlier I made it so the number of clicks with each button stores in a .txt file. Now I basically need to make it so a person can press a certain button only once.
This is ip.txt. The number to the left is button ID, to the right is IP of the person that clicked that button.
click-001||127.0.0.1
click-002||
This is very simple. I need to make sure it stores ip when I click on my PC, then stores another IP when I click on my pad - and stops whatever I do next. Now for the last few days it's been doing anything except that!
My current code with isset. That sees the first IP but doesn't add the second:
$file2 = 'ip.txt'; // path to text file that stores counts
$fh2 = fopen($file2, 'r+');
$ip_addr = $_SERVER['REMOTE_ADDR'];
$lines2 = '';
while(!feof($fh2)) {
$line2 = trim(fgets($fh2));
if ($line2) {
$line2 = explode('||', $line2);
if(isset($line2[0], $line2[1])) {
$item2 = trim($line2[0]);
if(!empty($item2)) {
if($item2 == $id) {
if(empty($line2[1])) {
$lines2 .= "$item2||$ip_addr\r\n";
file_put_contents($file2, $lines2);
} else {
// this is where it always fails
if (!isset($ip_addr)) { $ip_all = $line2[1] . " " . $ip_addr;
$lines2 .= "$item2||$ip_all\r\n";
file_put_contents($file2, $lines2);
} else {
echo "lul";
}
}
}
}
}
}
}
fclose($fh2);
I also tried this with in_array function:
$ip_all = array($line2[1]);
if (!in_array($ip_addr, $ip_all)) {
array_push($ip_all, ',' , $ip_addr);
$ip_fin = implode($ip_all);
$lines2 .= "$item2||$ip_fin\r\n";
file_put_contents($file2, $lines2);
^ This one also sees the first IP and adds the second, but then fails to find whether the IP is already there and just keeps adding copies when I click.
This is brutal. What am I doing wrong and is there an easier way?
Use MySQL database to accomplish this.
Using a text file is super inefficient and can cause conflicts when multiple users liked at the same time!
Insert the IP to database everytime a user clicked the 'Like' button and then use a select query to determine if this IP has liked the picture before.
I do not recommend using just IP tho as some ISP gives dynamic IP that changes the IP (Public IP) address every few seconds.
Use cookies to store a unique cookie for a user (if they are not logged in) or just ask the user to login first before voting!
Information about MySQL Insert and Select are everywhere on Google.
Here's one : https://www.w3schools.com/sql/
best method: use a database or use XML (XML have very useful library)
text file method:
get file and edit...
$id = "...";
$ip="...";
$file2 = file('ip.txt');
$file2 = array_map(
function($current_line) use ($id,$ip) {
$current_line = explode('||', $current_line);
if($current_line[0] == $id){
$current_line[]=$ip;
}
return join("||",$current_line);
},$file2
);
file_put_contents('ip.txt', implode('\n', $file2));
I am trying to write a php script to confirm an email address. I am using a file instead of a database to store user info which is outside the root directory. The file is csv.
When I try to store its contents in an array and print it, it works but when I try to compare an element from the array, it doesn't work. And also I want to write the email address of the user in csv as the last entry on the same line as other info.
Please help.
<?php
$rows[] = array();
$username = $_GET["username"];
$passkey = $_GET["passkey"];
$userdata = fopen("/****/*********/*****/$username.csv", "r");
$email = $_GET["email"];
$line = file_get_contents("/****/********/*****/$username.csv");
$rows = explode(",", $line);
print_r ($rows);
$newrows = trim($rows[6]);
$newpasskey = trim($passkey);
if($newrows == $newpasskey)
{
echo "Email-Id confirmed.";
fclose($userdata);
$userdata = fopen("/****/********/******/$username.csv", "a+");
fwrite($userdata, ",".$email);
fclose($userdata);
}
?>
I suggest you take a look at PHPs csv functions to ease loading/writing .csv data.
http://php.net/manual/en/function.fgetcsv.php and http://php.net/manual/en/function.fputcsv.php
Also, in your code, make sure that $username and $passkey are set, trimmed and sanitized before continuing.
You might also want to switch from GET to POST method in your form, I personally wouldn't want my password to be seen in the URL.
Try this:
$passkey = trim($passkey);
$stored_pass = trim($rows[6]);
if($stored_pass == $passkey)
{
//do stuff here
}
I found out the reason.I had made a mistake while entering the user info onto the file. I changed the php script that enters user info to the file. Now it works perfectly.
What I'm trying to do is check a file named ip-addresses.php in the same directory for a specific IP address and if the IP is NOT in the file then I want to assign the value of spark
Here is what I have so far:
$ip =
if( $ip ) {
$value = "spark";
}
?>
So what I'm trying to do is have the value $ip check the php file for some IPs and then assign the value of "spark"
How do I do this?
The function file() reads lines of a file as an array, making it easy to check for existing elements with in_array().
$list = file("ip-addresses.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (in_array($_SERVER['REMOTE_ADDR'], $list))
{
$value = "spark";
}
You need to read in the file first (if it is a php file you could also just create a function that returns an array for IPs and call it directly. Then look for the specific ip in the generated array (would be generated from reading the file) and if it is false set the ip to "spark".
// if you want to create another function in another .php file
include_once('ip-addresses.php');
$ip_array = get_ip_list();
// if you want the ips in a newline line separated .txt file
$ip_array = file('ip-addresses.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$ip = '127.0.0.1'; // theres no place like 127.0.0.1 but you can change this to what you want
if (!in_array($ip, $ip_array)) {
$ip = 'spark';
}
Basically to keep it short I have an assignment for college where I have to make a few scripts.
In one of these I have to make a scripts that records when data is entered wrong in a log in form. So it will take the users IP address and place it into a text file followed by the time, date, error name (e.g. wrong username and password, wrong name, w.e.), error page and attempts made.
I have figured out:
how to get the users ip
how to get the time and date
how to record the attempts
Now, what I want to do: I want the script to search for the users IP address and if this IP address has already been recorded for a failed attempt, instead of making a new record I want it to just add 1 to the attempts made to that IP address, update the time and date. Only in the case that this IP address has not been recorded a new record should be created.
if IP ALREADY EXISTS{
FIND AMOUNT OF ATTEMPTS
attempts++;
}
else{
ADD IP;
ADD TIME;
ADD DATE;
ADD REASON;
attempt=1;
}
this is what i have so far:
<?php
$time = date("h:i:sa");
$date = date("d/m/y");
$error = "Incorrect Data Entered";
$attempts = 0;
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$myFile = "errorLog.txt";
$file = fopen($myFile, 'a') or die("can't open file");
$searchfor = "$ip";
// the following line prevents the browser from parsing this as HTML.
header('Content-Type: text/plain');
// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($myFile);
// escape special characters in the query
$pattern = preg_quote($searchfor, '$ip');
// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
echo "Found matches:\n";
echo implode("\n", $matches[0]);
}
else{
$attempts = 1;
$stringData = "$ip, $time, $date, $error, $attempts\n";
fwrite($file, $stringData);
fclose($file);
}
?>
If you simply append to the same text file over and over then if you really want to add up the number of attempts by each individual user, then your going to need to rewrite the full txt file as far as I'm aware.
If you want to make it easier for yourself then you can write your txt file in such a way that you can easily obtain the values you need out of it, such as the ip address.
You could write each line like:
IPADDRESS,ERROR CODE,ATTEMPTS /n
Then when you want to change that line you'll need to keep a record of which line it is. A loop will be required to parse your txt file.
So the way I would attempt it would be:
Store text from file into a variable.
Use the explode() function to create an array of records. ( Like a row in a database ). I would use it like $rows = explode("/n" , $txt);
Loop through the rows. I would probably use foreach( $rows as $row) for this.
Keep track of the row number. So create a variable for it and iterate it.
Use the explode() function again to create a list($ip, $err, $attempts) by doing: list($ip, $err, $attempts) = explode("," , $row);
Now use normal php if() function to check to see if the two ips match, if the error codes are the same.
If they do, you can do $attempts++. Now the tricky/essential part.
You will need to create a string up to but NOT including that row and place it into a variable call it something like $firstpart.
You will also need to do the same for the rows after the affect row. eg $lastpart
Now create a new string for your affected row. Easily done: $str = $ip . "," . $err . "," . $attempts;
Finally, write your txt file using the variables, in the order: $firstpart, $str, $lastpart.
Not sure if this will work, not sure how practical this is, but at the very least I hope it helps you to get some sort of brainwave for how to approach your problem.
Hello there so I just setup this basic poll, I inspired myself from something I found out there, and it's just a basic ajax poll that waves the results in a text file.
Although I was wondering, since I do not want the user to simply mass-click to advantage / disadvantage the results, i thought about adding a new text file that could simply save the IP, one on each line, and then checks if it's already logged, if yes, display the results, if not, show the poll.
My lines of code to save the result are:
<?php
$vote = $_REQUEST['vote'];
$filename = "votes.txt";
$content = file($filename);
$array = explode("-", $content[0]);
$yes = $array[0];
$no = $array[1];
if ($vote == 0)
{
$yes = $yes + 1;
}
if ($vote == 1)
{
$no = $no + 1;
}
$insert = $yes."-".$no;
$fp = fopen($filename,"w");
fputs($fp,$insert);
fclose($fp);
?>
So I'd like to know how I could check out the IPs, in the same way it does basically.
And I'm not interested in database, even for security measures, I'm alright with what Ive got.
Thanks to any help!
To stop multiple votes, I'd set a cookie once a user has voted. If the user reloads the page with the voting form on it and has a cookie, you could show just the results, or a "You have already voted." message. Note that this will not stop craftier people from double-voting - all they would have to do is remove the saved cookie, and they could re-vote.
Keep in mind though that IPs can be shared so your idea of storing IPs might backfire - people on a shared external-facing IP won't be able to vote, as your system will have registered a previous vote from someone at the same IP address.
easiest way is to write data to file is
file_put_contents($filename, $data)
and to read data from file
file_get_contents($filename);
To get IP Address of the user
$_SERVER['REMOTE_ADDR']
See php manual for file_put_contents for more information and file_get_contents
Here is sample code
<?php
// File path
$file = 'votedips.txt';
// Get User's IP Address
$ip = $_SERVER['REMOTE_ADDR'];
// Get data from file (if it exists) or initialize to empty string
$votedIps = file_exists($file) ? file_get_contents($file) : '';
//
$ips = explode("\n", $votedIps);
if (array_search($ip, $ips)) {
// USER VOTED
} else {
$ips[] = $ip;
}
// Write data to file
$data = implode("\n", $ips);
file_put_contents($file, $data);
?>
You can use file_get_contents to save the file's content into a variable and then use the strpos function to check if the IP exists in that variable.
For example:
$ipfile=file_get_contents('ip.txt');
if (strpos($ipfile, $_SERVER['REMOTE_ADDR'])!==FALSE) // show the results
else // show the poll
Be careful with storing IPs in a text file, and then using file_get_contents() and similar functions for loading the data/parseing. As an absolute worst case, assuming that every possible IP address used your system to vote, you'd end up with a text file in the many many gigabytes in size, and you'd exceed PHP's memory_limit very quickly.