Build if statement from variable string - php

I am wanting to create an if(){} statement from the information specified in a variable.
My current code creates the string from a foreach loop, I am trying to filter out IP addresses in my code from being entered into my database.
Code that creates the string:
//Set excluded IP's
$exclude = "10.1.1.0/24, 192.168.1.0/24";
//Convert excluded to ranges
$ranges = cidrToRange($exclude);
//Build IP address exclusion if statement
$statement = NULL;
foreach($ranges as $ip_ranges) {
$statement .= " !((".ip2long($ip_ranges['start'])." <= $ip_address) && ($ip_dst <= ".ip2long($ip_ranges['end']).")) AND ";
}
//Strip and at end
$statement = rtrim($statement, "AND ");
The $ip_address variable needs to be inserted into the if statement afterwards(later in the script)
The $statement output of this code with the values specified in the $exclude variable will output:
!((167837952 <= $ip_address) && ($ip_address <= 167838207)) AND !((3232235776 <= $ip_address) && ($ip_address <= 3232236031))
I am wanting to use that string in an if statement, so the final result should look like:
if(!((167837952 <= $ip_address) && ($ip_address <= 167838207)) AND !((3232235776 <= $ip_address) && ($ip_address <= 3232236031))) {
//Do this
}
Is this possible to implement into my code?

Building a dynamic if statement is one thing, testing it is another. A simple alternative is to just search through the list and check if the IP address falls into the range. This checks each item and as soon as it matches it will stop and $save will be false.
//Convert excluded to ranges
$ranges = cidrToRange($exclude);
// Check if IP is to be saved -
$save = true;
foreach ( $ranges as $ip_ranges) {
if ( $ip_ranges['start'] <= $ip_address && $ip_address <= $ip_ranges['end'] ) {
$save = false;
break;
}
}
This assumes that $ip_address is also a long and not a string, something like...
$ip_address = ip2long("10.10.0.1");

I have figured out a way to do what I was wanting
My code
//Check if IP address is in a range
function check_ip_range($ip_address, $ip_ranges){
$ip_address = ip2long($ip_address);
foreach($ip_ranges as $ranges) {
if((ip2long($ranges['start']) <= $ip_address && $ip_address <= ip2long($ranges['end']))) {
//echo long2ip($ip_address)." is between ".$ranges['start']." and ".$ranges['end']."<br>";
return(true);
}
}
return(false);
}
I now have my code in my script like this:
//Configure ranges to exclude from accounting
$config['accounting']['exclude'] = "10.0.0.0/8";
//Convert ranges to array start and end
$exclude_ranges = cidrToRange($config['accounting']['exclude']);
//If IP is not in range
if(!check_ip_range($ip_address, $exclude_ranges)) {
//Do this
}

Related

Problem in code that must not repeat the same number in PHP

I've written this function that returns a time(number )that must not exist in the same day in the database which means that the same time must not be repeated but when I execute it the time(number) is repeated
can you help me sort this one out?
screen shots of the tables
https://files.fm/u/9aw9yc8x
note: the table is empty and it will be filled when the entire code is executed I have just posted the function that must not repeat the time.
function checkTime($className,$day,$conn){
global $numberLimet,$Daily,$UserLimt,$exist;
$sqlHoure = "SELECT * from schedule WHERE classname='".$className."'";
$hourQuery = mysqli_query($conn,$sqlHoure);
$h = array();
while ($hour = mysqli_fetch_assoc($hourQuery)){
$h[$hour['hour']] = $hour['day1'];
// array_search();
}
$number = rand(1,7);
if(array_search($day,$h) && array_key_exists($number,$h)){
return 'error';
}else{
if($hour['hour'] != $number && $hour['day1'] != $day){
$numberLimet++;
if($numberLimet == $Daily){
$UserLimt = 1;
$FristAdd = false;
echo("UserLimt" . $UserLimt);
return 'errorLimit';
}else{
return $number;
}
}else{
}
}
return $h;
}

how to compare the first three octets of two Ip adresses contained in two PhP variables

I have two php variables which contains two ipv4 addresses, i need to compare the first three octets and return true if they match, and false if they don't. Help for writing a block of code is appreciated.
<?php
include('adodb/adodb.inc.php');
mysql_connect("173.86.45,9","abcd","1236");
mysql_select_db("vc");
$pl=mysql_query("SELECT stat_ip from Hasoffers");
$count=mysql_num_rows($pl);
while($row=mysql_fetch_array($pl))
{
$stat_ip=$row['stat_ip'];
echo sec($stat_ip)."<br>";
}
function sec($stat_ip)
{
$result = mysql_query("select stat_ip from Hasoffers where stat_ip ='".$stat_ip."'");
if(condition to check if the octets match)
{
//i need to write the condition if within the table Hasoffers, there are more than 2 'stat_ip'(column) values, having the same 3 octets.
printf("true");
}
else
{
printf("false, octets don't match");
}
return $num_rows;
}
?>
Simple way to implement this is:
$ip1 = '192.168.0.1';
$ip2 = '192.168.0.2';
$ip1 = explode('.', $ip1);
$ip2 = explode('.', $ip2);
if ($ip1[0]==$ip2[0] && $ip1[1]==$ip2[1] && $ip1[2]==$ip2[2]) {
//your code here
}
EDIT:
Try to replace your sec() function with this one(read the comments),and edit it.
function sec($stat_ip)
{
$octets = explode('.', $stat_ip);
$first_three = $octets[0].'.'.$octets[1].'.'.$octets[2].'.'; //this looks like 192.168.0.
$result = mysql_query("SELECT stat_ip from Hasoffers where stat_ip LIKE '".$first_three."%'"); //this gives you all ip's starting with the current ip
if (mysql_num_rows($result)>1)
{
//we have more than one ip starting with current ip
//do something here
}
else
{
//result returns 1 or 0 rows, no matching ip's
}
//return $something;
}
The solution using strrpos and substr functions:
$ip1 = '192.168.10.121';
$ip2 = '192.168.10.122';
// the position of the last octet separator
$last_dot_pos = strrpos($ip1, '.');
$is_matched = substr($ip1, 0, $last_dot_pos) == substr($ip2, 0, $last_dot_pos);
var_dump($is_matched);
The output:
bool(true)
Use this code:
$ipOne = "192.168.1.1";
$ipTwo = "192.168.1.2";
$ipOneParts = explode(".", $ipOne);
$ipTwoParts = explode(".", $ipTwo);
if(($ipOneParts[0] == $ipTwoParts[0]) &&
($ipOneParts[1] == $ipTwoParts[1]) &&
($ipOneParts[2] == $ipTwoParts[2])){
return true;
} else {
return false;
}
convert them into array using explode using "." and compare the first index of both array.

Retry function when string not found

I have a function that scrapes data using a list of proxies with curl. It selects a random proxy each time the function is called. However sometimes a proxy can fail or timeout.
When the connection fails/timeout I would like to repeat the function up to 3 times until the data is returned.
The way I would like to test if the connection is bad is by checking if a string exists in the output like this:
$check = stripos($page,'string_to_check');
if($check > 0){
return $page; //String found. Return scraped data.
}
else {
//String not found. Loop the script
}
How would I get the whole function code to repeat if the string doesn't exist?
$max_tries = 3;
$success = false;
//try 3 times
for( $i = 0; $i < $max_tries; $i++ ) {
$page = your_scrape_function();
$check = stripos($page,'string_to_check');
if($check > 0){
$success = true;
break; //String found. Break loop.
}
}
// double check that the string was actually found and you didn't just exceed $max_tries
if( ! $success ) {
die('Error: String not found or scrape unsuccessful.');
}

$_SERVER['REMOTE_ADDR' string and changing subnets

I want to expand the IP range that my ~$_SERVER['REMOTE_ADDR'~ check for. The following works and only allows the 10.0.4.* subnet access to the site:
$chk = "10.0.4.";
if( substr($_SERVER['REMOTE_ADDR'],0,strlen($chk)) !== $chk)
$wgGroupPermissions['*']['read'] = false;
When I modify the $chk string to open the site to my entire local network I end up opening the site to the entire world.
$chk = "10.0.";
if( substr($_SERVER['REMOTE_ADDR'],0,strlen($chk)) !== $chk)
$wgGroupPermissions['*']['read'] = false;
I only want my local subnet 10.0.. to have read access to the site. How do I do this?
Using mask is a better way than spliting strings:
function testSubnet($ip, $subnet, $mask) {
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = ip2long($mask);
return ($ip & $mask) == ($subnet & $mask);
}
var_dump(testSubnet('10.0.0.1', '10.0.0.0', '255.255.255.0'));
var_dump(testSubnet('10.0.0.2', '10.0.0.0', '255.255.255.0'));
var_dump(testSubnet('10.0.1.1', '10.0.0.0', '255.255.255.0'));
var_dump(testSubnet('10.0.1.1', '10.0.0.0', '255.255.0.0'));
In this case:
if(testSubnet($_SERVER['REMOTE_ADDR'], '10.0.4.0', '255.255.255.0')) {
// Anything, blablabla...
}
Why can't you just do:
$z = $_SERVER['REMOTE_ADDR'];
function check($ip, $octet = 2) {
$allow = explode(".", "10.0.0.1");
$ipa = explode(".", $ip);
for($i = 0; $i < $octet; $i++) {
$ch .= $ipa[$i];
$ah .= $allow[$i];
}
return $ch == $ah;
}
echo check($z);
Where $octet is the amount of octets you want to match.. The default is 2.
You could use the header() function?
Try this.
$allowed_ip = "10.0.4";
if (!strstr($_SERVER['REMOTE_ADDR'],$allowed_ip))
header("Location: login.php");
// include("login.php");
/* The user will be redirected to another page or you could
always include your login.php page and just continue from there. */

Deleting DB records which are not in .csv file - efficiency?

I'm currently working on a .csv import which imports agenda items (such as events) and places them in a MySQL database. I've got the gist of it working, there is however a troublesome piece of code which I can't seem to wrap my head around on how to fix it or make it more efficient/better.
The part of code which is troublesome for me is when a event is held every -lets say- tuesday and sunday from 2012-06-01 'till 2013-04-01 and you want to check if some of these values are allready in the DB (because a user might import the .csv file again with some adjusted values). My current code eventually implements the correct values in to the DB, but the way it is done is kind of a hassle. If the file gets imported again all values from sunday get deleted again because my check goes through a foreach on tuesday first, where it will check if the DB values match with the values generated for tuesday. After the checks are done and the values are inserted into the DB my foreach checks all values for sunday (tuesday does not get deleted because I keep an array with all previous inserted values) and then inserts them again.
So basically when I import a .csv file it removes and then inserts the same values, and my question is how would I prevent this?
Also, if you see any way to improve this code at all (because I really feel it's not efficient to begin with in the first place) please say so, it's much appreciated.
Here is the code that checks for the repetition of events, if you need any clarfication or other code please let me know:
//REPEAT DAYS OF THE WEEK
if(!empty($repeatDayOfTheWeek) && $repeatDayOfTheWeek != '')
{
$daysOfTheWeek = explode(',', $repeatDayOfTheWeek);
foreach($daysOfTheWeek as $key => $dayOfTheWeek)
{
if(!is_numeric($dayOfTheWeek))
{
continue;
}
unset($agendaI->agendaItemValues['stopDate']);
$beginDate = strtotime($tempStartDate);
$endDate = strtotime($tempStopDate);
$dayDates = array();
$arrayDatesInDb = array();
if(!isset($previousInserts))
{
$previousInserts = array();
}
if($beginDate != '' && $endDate != '')
{
while($beginDate <= $endDate)
{
if(date('N', $beginDate) == $dayOfTheWeek)
{
$dayDates[] = date('Y-m-d', $beginDate);
}
$beginDate = strtotime("+1 day", $beginDate);
}
$datesInDb = $agendaI->getAgendaItemsByExternId($externId);
if(empty($datesInDb))
{
foreach($dayDates as $dayDate)
{
dump("Empty DB - INSERT: ".$dayDate);
$agendaI->setAgendaItemValue('startDate', $dayDate);
$agendaI->saveAgendaItem();
$previousInserts[] = $dayDate;
}
}
else
{
dump('DB with records');
foreach($datesInDb as $dateInDb)
{
if(!in_array($dateInDb->startDate, $dayDates) && !in_array($dateInDb->startDate, $previousInserts))
{
dump("Not in Item-array, but in DB - DELETE: ".$dateInDb->startDate);
$agendaI->deleteAgendaItem($dateInDb->id);
}
}
foreach($dayDates as $dayDate)
{
foreach($datesInDb as $dateInDb)
{
if($dayDate == $dateInDb->startDate)
{
$arrayDatesInDb[] = $dateInDb->startDate;
dump("In array & in DB - UPDATE: ".$dateInDb->startDate);
$agendaI->setAgendaItemValue('id', $dateInDb->id);
$agendaI->saveAgendaItem();
$previousInserts[] = $dayDate;
}
}
}
unset($agendaI->agendaItemValues['id']);
foreach($dayDates as $dayDate)
{
if(!in_array($dayDate, $arrayDatesInDb))
{
dump("Not in DB-array but in Item-array - INSERT: ".$dayDate);
$agendaI->setAgendaItemValue('startDate', $dayDate);
$agendaI->saveAgendaItem();
$previousInserts[] = $dayDate;
}
}
}
The following fields are in the .csv:
"Datum" "Tijdstip" "Evenement" "Locatie" "Website" "Toelichting" "Duits" "engels" "startdatum" "stopdatum" "herhalen dag van de week" "externid" "categorie" "via"
in other words
I need to check if the records in the DB are the same as in the .csv. If the csv does not have a record that the DB has I need to delete it from the DB (which my current code does, just not very efficient)
Rather than implementing your checks in PHP, you can define a UNIQUE index across the startdatum, stopdatum and herhalen dag van de week columns; then use REPLACE with your LOAD DATA command to replace any existing record that matches on those fields with the new one:
ALTER TABLE events ADD UNIQUE INDEX (startdatum, stopdatum, dag);
LOAD DATA INFILE '/path/to/foo.csv'
REPLACE
INTO TABLE events;
I eventually solved it in the following way without using a foreach for each $daysoftheweek and using array_diff:
//REPEAT DAYS OF THE WEEK
if(!empty($repeatDayOfTheWeek) && $repeatDayOfTheWeek != '')
{
$daysOfTheWeek = explode(',', $repeatDayOfTheWeek);
$agendaI->setAgendaItemValue('stopDate', '');
$beginDate = strtotime($startDate);
$endDate = strtotime($stopDate);
$dayDates = array();
$dbValues = array();
$dbValues['datum'] = array();
$latestDbValues = array();
$toBeDeletedKeys = array();
while($beginDate <= $endDate)
{
if(in_array(date('N', $beginDate), $daysOfTheWeek))
{
$dayDates[] = date('Y-m-d', $beginDate);
}
$beginDate = strtotime("+1 day", $beginDate);
}
$evenementenInDb = $agendaI->getAgendaItemsByExternId($externId);
if(!empty($evenementenInDb))
{
foreach($evenementenInDb as $evenementInDb)
{
$dbValues['agendaid'][] = $evenementInDb->id;
$dbValues['datum'][] = $evenementInDb->startDate;
}
}
foreach($dayDates as $dayDate)
{
$key = array_search($dayDate, $dbValues['datum']);
if($key !== false && is_numeric($key))
{
//UPDATE
$agendaI->setAgendaItemValue('id', $dbValues['agendaid'][$key]);
$agendaI->setAgendaItemValue('startDate', $dayDate);
$agendaI->saveAgendaItem();
$latestDbValues[] = $dayDate;
dump('UPDATE');
}
else
{
//INSERT
unset($agendaI->agendaItemValues['id']);
$agendaI->setAgendaItemValue('startDate', $dayDate);
$agendaI->saveAgendaItem();
$latestDbValues[] = $dayDate;
dump('INSERT');
}
}
$toBeDeleted = array_diff($dbValues['datum'], $latestDbValues);
foreach($toBeDeleted as $value)
{
$toBeDeletedKeys[] = array_search($value, $dbValues['datum']);
}
foreach($toBeDeletedKeys as $toBeDeletedKey)
{
//DELETE
$agendaI->deleteAgendaItem($dbValues['agendaid'][$toBeDeletedKey]);
dump('DELETE');
}
}
else
{
//Normal, non repeating event
//INSERT
if(!empty($agendaItem) && is_numeric($agendaItem->id))
{
$agendaI->setAgendaItemValue('id',$agendaItem->id);
}
$agendaId = $agendaI->saveAgendaItem();
}

Categories