As far as your original question, using file_exists()
is quicker for small numbers of bans (about <1000 bans) whereas using MySQL is quicker for larger numbers. The connection is made to the database only one time and the answer is sent back only one time, so the "bottleneck" of MySQL only adds a set, constant amount of time to the required time to do the query. MySQL (and other database) software then scales extremely well because there is a constant byte-width for each row, so it need only check bytes nRX to nRX+Y for integer multiples of n.
In older file systems the Operating System can not make such an assumption since files can be of variable length. Thus it would scan for the end_of_file
bit. Newer operating systems create a database of every file (The "File Allocation Table") at the beginning of the partition and it need merely search this. The problem is- the more files on the computer, the longer it takes to search this table. Also, fragmentation of the drive can make it harder to find if a file still exists. These little slow downs don't equal the time it takes to connect to an SQL database... for small numbers of bans.
What would be an even better solution would be to have a text file containing one ban per line.
bans.txt:
23.23.23.23
192.168.1.42
200.200.200.200
Then you just use strpos($file_contents, $_SERVER["REMOTE_ADDR"]
. Note that the fewer lines of PHP you have, the quicker it will ultimately run since the C back-end of PHP is about 100x quicker than the interpretation. Therefore in two lines we can get_file_contents()
(dump the contents to RAM) and strpos()
(search for a string within the RAM) and it's entirely handled by the C back-end, which iterates through quite quickly.
There are even quicker ways to do it, too, if you're willing to write your own database that keeps the bans listed numerically (allowing binary search).
Although as several people have already stated, this is not where any main bottleneck will occur in your server. Optimizing the "check for ban" portion of your website will net a 0.01% speed increase to your whole site. What you want to be really careful to optimize are loops that run >100 times, calls to remote servers, and queries which return several lines of a database to be parsed.
Also, don't write a function to perform something which already has a built-in PHP function. I spent a year manually parsing string with hundreds of substr(strpos())
lines before I learned how to use preg_replace()