简体   繁体   English

仅重定向一次并保存访问者IP

[英]redirect only once and save visitor ip

the code works fine but when it has 200 ip stored it deletes it automatically and I want it to not delete any ip unless I delete them manually 该代码可以正常工作,但是当它存储了200个IP时,它会自动删除它,并且我希望它不要删除任何IP,除非我手动删除

$ipfile = "ips.txt";
$ips = explode("\n",file_get_contents($ipfile));
$isban = 0;
foreach($ips as $ip) {
    $ip = explode(" ",$ip,2);
    if($_SERVER['REMOTE_ADDR'] == $ip['0']) {
        $isban++; 
    }
}
if(!empty($isban))
{
    die("IP IS BANNED!");
}
else
{
    $ips[] = $_SERVER['REMOTE_ADDR']." ".date("d/m/y");
    $ips = implode("\n",$ips);
    file_put_contents($ipfile,$ips);
    header('Content-Type: text/html; charset=UTF-8');
    header('Location: http://www.google.com/');
    exit;
}

I want it to store all the ip without deleting it, it does not matter if I have to use a database so that it can work better or some solution that someone brings to me. 我希望它存储所有ip而不删除它,如果我必须使用数据库以使其能更好地工作或有人带给我的某种解决方案也没关系。

This code has no error handling, therefore it is impossible to learn early about what fails so that you can't address it specifically. 该代码没有错误处理,因此无法及早了解失败原因,从而无法明确解决。

What does that mean? 这意味着什么? Let's see exemplary this line of code (I've taken it from the code of your question, but I could have taken it from numerous other examples, as such kind of a mistake is quite common in PHP code examples on Stackoverflow): 让我们看一下示例代码行(我从问题代码中获取了代码,但我可以从许多其他示例中获取它,因为这种错误在Stackoverflow上的PHP代码示例中非常普遍):

$ips = explode("\n",file_get_contents($ipfile));

If file_get_contents() fails to load the file it normally is only noticed if you expect the list of $ips has entries and then unexpectedly it does not. 如果file_get_contents()无法加载文件,则通常只有在您期望$ips列表中包含条目,而后意外地没有时,才会注意到该文件。

That is because the return value of file_get_contents() is not checked whether or not an error appeared. 这是因为未检查file_get_contents()的返回值是否出现错误。

In PHP it is quite common that a function not only returns the result of the function but as well - in case of an error - the error result of it. 在PHP中,一个函数不仅返回函数的结果,而且在出现错误的情况下还会返回其错误结果,这是很常见的。

For every function which differs that way in the return value, it needs to be treated for the different ways. 对于每个返回值不同的函数,都需要以不同的方式对待。

This is especially crucial w/ i/o operations like reading from a file and writing to a file. 这对于进行w / i / o操作(例如从文件读取和写入文件)特别重要。 you actually want to learn when these operations fail and then proceed accordingly. 您实际上想了解这些操作何时失败,然后进行相应的操作。

To repeat the example: If reading the file fails, this is not an empty string to progress with resulting in data-loss of all recordsets (in your case your file actually is a database and one record is one line in it). 重复该示例:如果读取文件失败,则这不是一个空字符串,将导致所有记录集的数据丢失(在您的情况下,您的文件实际上是数据库,一条记录在其中一行)。 But if not treated differently, it will become so, which is in your example the deletion of all IPs. 但是,如果没有区别对待,它将变成事实,在您的示例中,这就是删除所有IP。

How To Solve? 怎么解决?

Review the use of I/O related functions in the code. 查看代码中与I / O相关的功能的使用。 This can be easily achieved by going through each function call and check the manual entries regarding their error handling and especially the return values. 可以通过遍历每个函数调用并检查有关其错误处理的手动条目(尤其是返回值)来轻松实现。

Then improve your code by handling these error conditions accordingly. 然后通过相应地处理这些错误情况来改进代码。

Further Outlook 进一步展望

Next to error handling there is also something called locks or locking regarding file operations, you could take a read into that to better control congruent execution of the same script as the file is a shared resource here. 除了错误处理之外,还有一些关于文件操作的锁定或锁定,您可以读一读,以更好地控制同一脚本的一致执行,因为此处文件是共享资源。

it is much easier using database. 使用数据库要容易得多。 Here is example. 这是例子。

In Mysql: 在Mysql中:

CREATE DATABASE addr;
USE addr;

CREATE TABLE ips (
  id INT AUTO_INCREMENT PRIMARY KEY,
  ip VARCHAR(45),
  visit_timestamp TIMESTAMP DEFAULT now()
);

In PHP: 在PHP中:

$conn = new mysqli('localhost','username','password','addr');

$remote_ip = $_SERVER['REMOTE_ADDR'];

$query2 = "SELECT * FROM ips WHERE ip = '$remote_ip'";

$isban = mysqli_num_rows($conn ->query($query2));


if($isban > 0){
    die("IP IS BANNED!");
}
else{

    $query = "INSERT INTO ips (ip) VALUE ('$remote_ip')";

    $conn->query($query);

    header('Content-Type: text/html; charset=UTF-8');
    header('Location: http://www.google.com/');
    exit;
}

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

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