I am trying to block a certain range of ips and i want to do it in php rather than .htaccess. I am using this: <?php $ip = $_SERVER['REMOTE_ADDR']; $sparray = file ("iplist.txt"); //$sparray[0]="127.0.0.1"; //$sparray[1]="111.11.11.1"; for ($j=0;$j<count($sparray);$j++){ $sparray[$i]=trim($sparray[$i]); } if (in_array($ip, $sparray)) { $block=1; } else{ $block=0; } echo $block."<br>"; print_r($sparray); //check the array ?> PHP: But it doesn't work. The value of $block is 0. When I comment out this line $sparray = file ("iplist.txt"); and instead remove the comments from the other two lines its working. The text file only contains the two ips for testing, but ultimately I will put all offenders there and fetch it from a server for all my sites (hence php instead of .htaccess). I am testing on my local machine 127.0.0.1. What am I missing? I have been banging my head forever on this. Andre
Why don't you put some error checking like : if (!($sparray = file ("iplist.txt")) { echo 'error opening file'; } else {....} PHP:
Thanks for the answer, but that doesn't solve the problem. The output of the script is: (the first line is generated by the echo statement and the last one by the print_r statement). Hence the file is opened correctly. I still don't get why $block is 0. Anyone knows the answer?
because you only set block to true if the ip that you're visiting from is an ip in the array ... I'm guessing it's not ...
But it is echo $block."<br>"; echo $ip."<br>"; print_r($sparray); echo "<br>"; PHP: If I put this in my code I get: 0 127.0.0.1 Array ( [0] => 127.0.0.1 [1] => 111.11.11.1 [] => ) So clearly my ip (localhost) is detected right and is contained in the array. If I change the code to include iplist.php which looks like this: <?php $sparray = array( '111.11.11.1', '127.0.0.1', ); ?> PHP: Then the detection works right. That doesn't make any sense to me.
ok, use this instead .... <? $iparray = split("\r\n", file_get_contents("ips.txt")); if(in_array($_SERVER['REMOTE_ADDR'], $iparray)) { die("BANNED"); } ?> PHP: OR <? $iparray = split("\n", file_get_contents("ips.txt")); foreach( $iparray as $banned ) { if( $_SERVER['REMOTE_ADDR'] == trim($banned) ) { die("BANNED"); } } ?> PHP: Both of the above code examples function with a ips.txt looking like 127.0.0.1 172.6.0.1 192.168.0.1 Code (markup): and both code examples work, theres only one explanation for this : I think that file() splits a file by newline characters ("\n"), however files authored inside windows will have carriage return and a newline character ("\r\n"), I have also discovered that php has the ability to detect line endings when it uses fopen wrappers ( near on everthing with file in the function name ), however this by default isn't set in an attempt to keep php multi-OS Hope that helps ..... In addition : I read in your post you wish to block certain ip ranges, the above code will not do that .... however <? $iparray = split("\n", file_get_contents("ips.txt")); foreach ($iparray as $ip ) { $regex[] = str_replace( array(".", "*"), array("\.", "([0-9]+)"), $ip ); } foreach( $regex as $banned ) { if(preg_match("/".trim($banned)."/", $_SERVER['REMOTE_ADDR'])) { die("BANNED"); } } ?> PHP: Will do exaclty that, the above code example works with a ips.txt that looks like 127.0.0.* 172.6.0.1 192.168.0.1 Code (markup): * is the wildcard character...... Thats gotta help right ?
Yeah, pretty cool. Thanks a bunch. I ran accross the ip range thing myself and my solution was to explode the string into an array with the . as delimiter and then check from the beginning on (this way I don't need a wildcard and my ranges look like this: 127.0.0 ). I will give it a try when I get home, just wanted to say thanks for spending the time on this.
Just wanted to add to this thread, you could save yourself some trouble by changing this: $iparray = split("\n", file_get_contents("ips.txt")); PHP: To this: $iparray=file('ips.txt'); PHP: file() returns an array split on \n
In the end result there is no difference. I was just giving you a tip for future reference. Using file() saves you the trouble of reading in a file and then splitting that into an array based on a string value. This could make a big difference in resource usage depending on the size of the text file. So it was just something I picked up along the way and wanted to pass on to you and the community. Just ignore my reply if it confuses the situation.
There is a difference, if the file being parsed for ips is authored inside windows, then numbers will not match becuase the variable will contain the ip and an invisible \r so unless you get to trim the variable then using in_array and file will fail in these circumstances, it looks for an exact match and it doesn't have one, so its one or the other .....
That's right Joe, it's not an issue with file() though. That's another reason it's better to go with file() instead of the other way.
it is an issue with file() like you said it splits files by \n chars and not \r\n so any variables will have \r on the end of them meaning if you cannot trim it you will not get a numerical match.
file() only looks for a line ending, if that's \n or \r\n it doesn't matter. Create a test case and you'll see what I mean. Yes, this will fail with \r only: $iparray = split("\n", file_get_contents("ips.txt")); PHP: This will work everytime: $iparray=file('ips.txt'); PHP: See this entry for more information: http://us2.php.net/file