checking a condition through data inside a textfile - php

I have been using a redirect feature in my website where users are redirected to sites which are white listed. I realized that the procedure to authenticate the domain names through traditional db calls are much time consuming therefore I introduced a method to get the db table written to a text file and do the redirecting authentication from there by match the domain names. so I got the table of white listed domain names to a text file(serialized) as follows
code
$trusted_domain = $_GET['go'];//these variables are taken from the url
$project_id = $_GET['project'];//these variables are taken from the url
$query = "SELECT projectid, domainname FROM domains";
$result = mysql_query($query);
while($row= mysql_fetch_assoc($result)){
$objData = $objData." ". serialize( $row). "\r\n";
}
$filePath = "data.txt";
if (is_writable($filePath)) {
$fp = fopen($filePath, "w");
fwrite($fp, $objData);
fclose($fp);
}
the textfile content
a:2:{s:9:"projectid";s:2:"19";s:10:"domainname";s:27:"_http._sctp.www.example.com";}
a:2:{s:9:"projectid";s:2:"28";s:10:"domainname";s:11:"www.abc.com";}
a:2:{s:9:"projectid";s:2:"46";s:10:"domainname";s:11:"www.abc.com";}
a:2:{s:9:"projectid";s:2:"70";s:10:"domainname";s:12:"www.test.com";}
a:2:{s:9:"projectid";s:2:"75";s:10:"domainname";s:15:"www.bulding.com";}
a:2:{s:9:"projectid";s:2:"80";s:10:"domainname";s:11:"www.abc.com";}
a:2:{s:9:"projectid";s:2:"82";s:10:"domainname";s:11:"www.abc.com";}
a:2:{s:9:"projectid";s:3:"100";s:10:"domainname";s:47:"https://www.google.com
https://www.facebook.com";}
Now the problem is, can anyone tell me how to match the two variables $trusted_domain and $project_id with each and every projectid and domainname inside the serialized text above. I mean if a user comes with a url
http://trackme.domain.com/redirect?project=75&go=www.building.com
how do I compare the values 75 and www.building.com with content in the text file.

I would consider setting up a Memcache server for this, especially if you have lots of domains in the list.
I think the following will work for you though if you are flexible about the data format of the saved file. This example uses JSON which is quicker and easier to process.
$query = "SELECT projectid, domainname FROM domains";
$result = mysql_query($query);
$objData = [];
while ($row = mysql_fetch_assoc($result)){
$objData[$row['projectid']] = $row['domainname'];
}
file_put_contents('data.txt', json_encode($objData));
And then you can process like so:
$trusted_domain = $_GET['go'];//these variables are taken from the url
$project_id = $_GET['project'];//these variables are taken from the url
$data = json_decode(file_get_contents('data.txt'), true);
if (isset($data[$project_id]) && $data[$project_id] === $trusted_domain)
{
// Domain matches
}
When the JSON is read it creates an array where the project id is the key and the value is the domain name.
I have assumed here that the project_id is unique and there is only 1 trusted domain per project. If that's not the case, you may have to tweak this a little for your exact needs. E.g:
while ($row = mysql_fetch_assoc($result)){
$objData[$row['projectid']][] = $row['domainname'];
}
Notice the extra []? This will create an array of domain names for the project id, you can then use this when parsing the file:
if (isset($data[$project_id]) && in_array($trusted_domain, $data[$project_id])) { }
Also I should add, avoid using mysql_* functions as they are being deprecated. Look into PDO instead.

Related

How to use array data received from GET in a mysqli query

I am passing several zip codes(retrieved by a previous lat/long search) and other data via GET to another page that will retrieve all listings from a database that contains those zip codes in the address.
So the url looks like this:
http://blahblahblah.com/listings.php?date=2015-10-23&zc=0=23547&1=28456&2=27678
My question is how do I loop through those zip codes in my db query? It seem like running a separate query for each zip code would be pretty taxing if given to many zipcodes.
$zc = array(); //initiate the array
$zc[0] = $_POST['zip']; // Add the starting zip code to the array
mysqli_query($conn, "select * zip_code within a certain range of lat and lng");
// return results
while($row = mysqli_fetch_assoc($sql)){
$zip = $row['db_zip'];
array_push($zip);
}
So there is how I am getting the info into the array. After that it is on to building the URL to display a link on a calendar for each day of the month that there is a listing.
//A ton of other stuff then
//echo the link using html_build_query() to add the zips to the get parameters.
echo ''.$d_count.'';
So then I am on to processing the info on the next page, which is where I am really confused.
Ok guys given the number of zip codes I could end up passing, GET was not going to work.
The solution that Mike gave was indeed correct, however, it had to be done by passing the zip codes to the next page via sessions.
Like so:
$_SESSION['zc'] = $zc;
and then imploding the array using the imploded data in the query:
$tmp = implode(", ", $_SESSION['zc']);
$sql = mysqli_query($conn, "SELECT * FROM listingss WHERE zipcode IN ($tmp) AND l_date = '$date'");
listings.php?date=2015-10-23&zc[]=23547&zc[]=28456&zc[]=27678
use implode function of php like this
$tmp = implode(",", $zc);
and then
SELECT * FROM TABLE WHERE zip_code in ($tmp);

Caching MySQL results with Memcache and sorting/filtering cached results

To help everyone understand what I'm asking I put forward a scenario:
I have user A on my web app.
There is a particular page which has a table that contains information that is unique to that user. Let's say it is a list of customers that only show for user A because user A and these customers are in region 5.
Other users are assigned to different regions and see different lists of customers.
What I would like to do is cache all of the results for each users list. This isn't a problem as I can use:
$MC = new Memcache;
$MC->addserver('localhost');
$data = $MC->get('customers');
if($data)
{
} else {
$data = $this->model->customersGrid($take, $skip, $page, $pageSize, $sortColumn, $sortDirection, $filterSQL, $PDOFilterParams);
$MC->set('customers', $data);
}
header('Content-Type: application/json');
return $data;
The challenge now is to somehow convert the SQL filter syntax that comes from my users table into a function that can filter and sort an array ($data is a JSON string that I would turn into an array if that's the right way to go).
Just for reference, here is the array of aliases I use for building the WHERE clause in my statements:
$KF = new KendoFilter;
$KF->columnAliases = array(
'theName' => 'name',
'dimensions' => 'COALESCE((SELECT CONCAT_WS(" x ", height, width, CONCAT(length, unit)) FROM products_dimensions,
system_prefs, units_measurement
WHERE products_dimensions.productId = product.id
AND units_measurement.id = system_prefs.defaultMeasurementId), "-")',
'gridSearch' => array('theName', 'basePrice')
);
$filterSQL = $KF->buildFilter();
My question is what is a good way to filter and sort memcache data as if it was an SQL query? Or does memcache have something already built in?
Memcache cannot do this - you can't replace your database with memcache (that is not what it is for), you can only store key => value pairs.
I think a better approach is to store each data for each user in a specific mem cache key.
So for example if user A with $user_id = 123 visits the page:
$data = $MC->get('customers_for_'.$user_id);
This way you only get the customers for user 123.
A more generic approach is to generate a hash for each sql query with it's params (but that might be overkill in most cases). For example if you have a query select ... from ... where a = #a and b = #b with variables $a and $b you could do the following (you must adapt this for kendo of course, but to get the idea):
$query = "select ... from ... where a = #a and b = #b";
# crc32 because it is fast and the mem key does not get too long
$sql_crc = crc32($query.$a.$b);
$data = $MC->get("customers_".$sql_crc);
To rule out (unlikely) hash collisions for different users, you could mix in the user id in the key, too:
$data = $MC->get("customers_for_".$user_id."_".$sql_crc);
BUT: If you start doing this all over the place in your app because otherwise it is too slow, then maybe the problem lies in your database (missing/wrong indexes, bad column definitions, complicated relations, etc.) and time should better be invested in fixing the DB than working around the issue like this.

PHP create a complex CSV file

I am in need to create a CSV file getting the data from a mySQL DB.
The fact is that I want the CSV tp be corrected labeled and not just writing the data like this:
id,name,url
1,thisismyname,thisismyurl
I need the CSV file to look well ordered and each data inserted in the relative column.
Also with the function I am going to add below I can only grab the data from the DB and write it to the CSV file as it is. But I need to work with the data and have the CSV labeled in this way:
Campaign Name:
Name of the campaign
Campaign Url:
Url of the campaign
Tot visits:
Tot of visits
Tot unique visits:
Tot of unique visits
id name url
1 thisname this url
2 thisname this url
3 thisname this url
4 thisname this url
5 thisname this url
This is the PHP code I have so far..I need to understand how to achieve a correct structure of the CSV with PHP and adding the lines in it the exact way I want..
Thanks for your help!
function genCSV($filename, $attachment = true, $headers = true) {
// send response headers to the browser
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=' . $filename);
$fp = fopen('php://output', 'w');
$query = "SELECT * FROM campaigns";
$result = mysql_query($query) or die(mysql_error());
if ($headers) {
// output header row (if at least one row exists)
$row = mysql_fetch_assoc($result);
if ($row) {
fputcsv($fp, array_keys($row));
// reset pointer back to beginning
mysql_data_seek($result, 0);
}
}
while ($row = mysql_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
}
Here is a much less elegant solution than the one proposed by #Tom Regner.
I needed to backup certain database tables (all those with a given prefix) but not others. This method, though somewhat slow, allows you to select exactly which tables and which columns from those tables are copied. It was originally written to allow each piece of data to be AES encrypted before being entered into the file but there are other uses for it. As written here, the result is a CSV file with the first line containing the list of columns for the table and the rest containing the data in CSV. It will stand adaptation to output the result of any sql into CSV, if you like.
Obviously: mysqlidb = mysqli databse resource, backups/ = directory to put finished files in.
FWIIW, here is the code:
$sql="SHOW TABLES LIKE 'yourtable%'";
$result = $mysqlidb->query($sql);
$tableresult=$mysqlidb->query($sql);
while($tables=$tableresult->fetch_assoc())
{
$keys=array_keys($tables);
$tablename=$tables[$keys[0]];
echo "Writing $tablename <BR>";
$file=fopen("backups/$tablename.enc","w");
$cols=array();
$sql="SHOW COLUMNS FROM $tablename";
$result=$mysqlidb->query($sql);
while($row=$result->fetch_assoc())
{
$cols[]=$row['Field'];
}
fputcsv($file,$cols);
$sql="SELECT * FROM $tablename";
$result=$mysqlidb->query($sql);
while($row=$result->fetch_assoc())
{
fputcsv($file,$row);
}
fclose($file);
}

store mysql results in SESSION array for later use (to check via in_array)

I currently have this :
require_once('auth.php');
auth.php:
session_start();
if(!isset($_SESSION['SESS_MERCHANT_ID']) || (trim($_SESSION['SESS_MERCHANT_ID']) == '')) {
header("location: login-form.php");
exit();
}
mybadges.php:
$mybadges = mysql_query("SELECT badge_id
FROM badges WHERE merchant_id = $current_userid ORDER BY badge_id DESC");
while ($result = mysql_fetch_array($mybadges)){
$badge_id = $result['badge_id'];
}
I wanted to know how I can store $result['badge_id']; in a $_SESSION array (like $_SESSION['badges']?)
a more sensible version of 'auth.php'
session_start();
if(empty($_SESSION['SESS_MERCHANT_ID'])) {
header("location: login-form.php");
exit();
}
a more sensible version of mybadges.php:
$sql = "SELECT badge_id FROM badges WHERE merchant_id = $current_userid ORDER BY badge_id DESC"
$res = mysql_query($sql) or trigger_error(mysql_error()." ".$sql);
in case there is only one bagde_id to store:
$row = mysql_fetch_array($res);
$_SESSION['badge'] = $row['badge_id'];
in case there are many id's (as one cannot say for sure from your code, what you need):
$badges = array();
while ($row = mysql_fetch_array($res)) {
$badge_ids[] = $row['badge_id'];
}
$_SESSION['badges'] = $badge_ids;
in general, to store anything an a session, just assign that anything to a session variable:
$_SESSION['badges'] = $badge_ids;
not a big deal.
a SESSION array become exectly what you wrote. $_SESSION['badges'] is a regular variable to use.
Note that you can save only scalars, arrays and objects. Not resources.
If I understand well your needs, you can simply do this :
$_SESSION['badges'] = $result['badge_id'];
Make sure that mybadges.php includes auth.php otherwise you won't have a session started. I'm assuming that's what you have but it doesn't show up that way in the code above. Assuming you have auth.php included, just do as sputnick said with
$_SESSION['badges'] = $result['badge_id'];
php sessions support multiple dimesion arrays.
$members=array();
foreach(mysql_fetch_array($memberresultset) as $key->$value)
$members[]=$value;
foreach($members as $mv)
$_SESSION["MEMBER"][]=$mv;
would work, for example.
Also something like this:
$_SESSION["badgeidnumbers"][]=$result["badgeid"]
But your would need to add them with foreach command, fetching more than one rows.
Extra brackets are for adding to the array using the new index number. you can write anything in the second brackets.
you also use some format like
$_SESSION["badgeidnumbers"][$result["badgeid"]]=$result["badgename"]
I do not recommend dividing your project into too many files. Normally, you shouldn't need session variables. Don't hesitate to ask ideas about the general structure of your application. It may save you a lot of time.

PHP DELETE immediately after select

I have a PHP server script that SELECTs some data from a MySQL database.
As soon as I have the result from mysql_query and mysql_fetch_assoc stored in my own local variables, I want to delete the row I just selected.
The problem with this approach is that it seems that PHP has done pass-by-reference to my local variables instead of pass-by-value, and my local variables become undefined after the delete command.
Is there anyway to get around this? Here is my code:
$query="SELECT id, peerID, name FROM names WHERE peer = $userID AND docID = '$docID' AND seqNo = $nid";
$result = mysql_query($query);
if (!$result)
self::logError("FAIL:1 getUsersNamesUpdate() query: ".$query."\n");
if (mysql_num_rows($result) == 0)
return array();
$row = mysql_fetch_assoc($result);
$result = array();
$result["id"] = $row["id"];
$result["peerID"] = $row["peerID"];
$result["name"] = $row["name"];
$query="DELETE FROM names WHERE id = $result[id];";
$result = mysql_query($query);
if (!$result)
self::logError("FAIL:2 getUsersNamesUpdate() query: ".$query."\n");
return $result;
You are overwriting your $result variable with your second statement:
$query="DELETE FROM names WHERE id = $result[id];";
$result = mysql_query($query); // result does not contain the array anymore
Change the name to something else. It has nothing to do with call-by-reference or such.
Actually, your first assignment of the values is unnecessary as $row is already an array:
$row = mysql_fetch_assoc($result);
$result = array();
$result["id"] = $row["id"];
$result["peerID"] = $row["peerID"];
$result["name"] = $row["name"];
You could just do:
$row = mysql_fetch_assoc($result);
// at the end
return $row;
Then you don't even have to change your variable name for the second statement. But consider to use meaningful variable names.
First of all, why not just use only one query to delete the row that interests you ?
Something like this should do the trick, I suppose :
delete
from names
where peer = $userID
AND docID = '$docID'
AND seqNo = $nid
Of course, don't forget to escape/convert the values that should be ;-)
This way, no need for a select query, followed by a delete one.
Second : to make your code more easier to read / understand / maintain, you should probably not re-use the same variable for several different purposes.
Here, your $result variable is used for more than one thing, and it makes things harder to understand :
resource returned by the first mysql_query
then, array containing data from the first row
then, resource returned by the second mysql_query
It's a bit confusing, and will, one day or another, lead to errors...
Actually, it already has ;-) : the third assignment is overriding the data you're getting with the second ones, and boom, you've lost the information that corresponds to the row you've just deleted ;-)

Categories