PHP/MySQL Printing Duplicate Labels - php

Using an addon of FPDF, I am printing labels using PHP/MySQL (http://www.fpdf.de/downloads/addons/29/). I'd like to be able to have the user select how many labels to print. For example, if the query puts out 10 records and the user wants to print 3 labels for each record, it prints them all in one set. 1,1,1,2,2,2,3,3,3...etc. Any ideas?
<?php
require_once('auth.php');
require_once('../config.php');
require_once('../connect.php');
require('pdf/PDF_Label.php');
$sql="SELECT $tbl_members.lastname, $tbl_members.firstname,
$tbl_members.username, $tbl_items.username, $tbl_items.itemname
FROM $tbl_members, $tbl_items
WHERE $tbl_members.username = $tbl_items.username";
$result=mysql_query($sql);
if(mysql_num_rows($result) == 0){
echo "Your search criteria does not return any results, please try again.";
exit();
}
$pdf = new PDF_Label("5160");
$pdf->AddPage();
// Print labels
while($rows=mysql_fetch_array($result)){
$name = $rows['lastname'].', '.$rows['firstname';
$item= $rows['itemname'];
$text = sprintf(" * %s *\n %s\n", $name, $item);
$pdf->Add_Label($text);
}
$pdf->Output('labels.pdf', 'D');
?>

Assuming that a variable like $copies is an integer of how many copies they want made, I would make the following modification:
// Print labels
while( $row = mysql_fetch_array( $result ) ){
// Run Once for Each Result
$name = $row['lastname'].', '.$row['firstname'];
$item = $row['itemname'];
$text = sprintf(" * %s *\n %s\n", $name, $item);
if( isset( $copies ) ) {
// The Copies Variable exists
for( $i=0 ; $i<$copies ; $i++ ) {
// Run X times - Once for each Copy
$pdf->Add_Label($text);
}
} else {
// The Copies Variable does not exist - Assume 1 Copy
$pdf->Add_Label($text);
}
}
This should provide the required functionality.

Related

PHP for loop with Database and API Data only calculates 1 result

I try to loop trough a php script to calculate a Total Holding of a Persons Portfolio. But my code only puts out one calculated field instead of all from the Database.
My DB looks like this:
id email amount currency date_when_bought price_when_bought
33 test#test.com 100 BTC 2019-04-17 4000
34 test#test.com 50 ETH 2019-04-17 150
My Code (pretty messy)
<?php
include('databasecon.php');
//// GET API JSON DATA
$coinData = json_decode(file_get_contents('https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRB,IOTA,XRP,XLM,TRX,LINK,USDT&tsyms=USD'), true);
//SELECT ALL MAIL
$result = mysqli_query($con, "SELECT DISTINCT email FROM user_data");
$email_array = array();
while($row = mysqli_fetch_array($result))
{
$email_array[] = $row['email'];
};
// PORTFOLIO ARRAYS
for ($i = 0; $i < sizeof($email_array); $i++) {
$sql = mysqli_query($con, "SELECT DISTINCT * FROM crypto_data WHERE email = '$email_array[$i]'");
while($row = mysqli_fetch_array($sql)){
$myCoins[$row['currency']] = array('balance' => $row['amount'],
'boughtprice' => $row['price_when_bought']);
};
// 0 VALUES FOR CALCULATION
$portfolioValue = 0;
$totalNET = 0;
$Value24H = 0;
// information in json path ['RAW'] so safeguard here to be sure it exists
if (isset($coinData['RAW'])) {
// then loop on all entries $cryptoSymbol will contain for example BTC and cryptoInfo the array USD => [...]
foreach($coinData['RAW'] as $cryptoSymbol => $cryptoInfo) {
// safeguard, check path [USD][FROMSYMBOL] exists
if (!isset($cryptoInfo['USD']) || !isset($cryptoInfo['USD']['FROMSYMBOL'])) {
// log or do whatever to handle error here
echo "no path [USD][FROMSYMBOL] found for crypto: " . $cryptoSymbol . PHP_EOL;
continue;
}
// Symbol in on your json path/array [USD][FROMSYMBOL]
$thisCoinSymbol = $cryptoInfo['USD']['FROMSYMBOL'];
$coinHeld = array_key_exists($thisCoinSymbol, $myCoins);
// Only retour held
if ( !$coinHeld ) { continue; }
// get price:
$thisCoinPrice = $cryptoInfo['USD']['PRICE'];
// get symbol holding:
if ($coinHeld) {
$myBalance_units = $myCoins[$thisCoinSymbol]['balance'];
};
// calculate total holdings:
if ($coinHeld) {
$myBalance_USD = $myBalance_units * $thisCoinPrice;
$portfolioValue += $myBalance_USD;
};
echo '<br>';
echo $email_array[$i];
echo $portfolioValue . PHP_EOL;
echo '<br>';
echo '<br>';
$myCoins = null;
}}};
?>
The Steps are:
1 API connection
2 Select Mail adresses from user_data and put them into an Array
3 start for-loop with size of the email_array
4 Query the crypto_data DB to get all results from that mail
5 Put all Data from crypto_data into Array
6 foreach loop the API
7 Calculations
8 Echo the results
9 null $myCoins
As a result, I get the right Mail Adress + the second row (id 33) calculated with the actual price. But my Result should also plus count id 33 and 34 to get the total result.
To clearify, I get "100 * Price of BTC" , but I need "100 * Price of BTC + 50 * Price of ETH"
Somehow my code only puts out 1 row, but does not calculate them like I want to do so here:
// calculate total holdings:
if ($coinHeld) {
$myBalance_USD = $myBalance_units * $thisCoinPrice;
$portfolioValue += $myBalance_USD;
};
Any help is appreciated, thank you very much.
There are few bugs in your code, such as:
You are setting $myCoins to null immediately after the first iteration of foreach loop, so array_key_exists() function will fail in the next iteration. Remove it entirely, there's no need of setting $myCoins to null.
Keep the below just inside the outer for loop. You should not print the portfolio value for each iteration of foreach loop, rather print the aggregated portfolio value for each email address.
echo '<br>';
echo $email_array[$i];
echo $portfolioValue . PHP_EOL;
echo '<br>';
echo '<br>';
Reset $portfolioValue value to 0 at the end of the for loop.
So your code should be like this:
<?php
include('databasecon.php');
// GET API JSON DATA
$coinData = json_decode(file_get_contents('https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,ETH,XRB,IOTA,XRP,XLM,TRX,LINK,USDT&tsyms=USD'), true);
//SELECT ALL MAIL
$result = mysqli_query($con, "SELECT DISTINCT email FROM user_data");
$email_array = array();
while($row = mysqli_fetch_array($result)){
$email_array[] = $row['email'];
}
// PORTFOLIO ARRAYS
for ($i = 0; $i < sizeof($email_array); $i++) {
$sql = mysqli_query($con, "SELECT DISTINCT * FROM crypto_data WHERE email = '$email_array[$i]'");
while($row = mysqli_fetch_array($sql)){
$myCoins[$row['currency']] = array('balance' => $row['amount'], 'boughtprice' => $row['price_when_bought']);
}
// 0 VALUES FOR CALCULATION
$portfolioValue = 0;
$totalNET = 0;
$Value24H = 0;
// information in json path ['RAW'] so safeguard here to be sure it exists
if (isset($coinData['RAW'])) {
// then loop on all entries $cryptoSymbol will contain for example BTC and cryptoInfo the array USD => [...]
foreach($coinData['RAW'] as $cryptoSymbol => $cryptoInfo) {
// safeguard, check path [USD][FROMSYMBOL] exists
if (!isset($cryptoInfo['USD']) || !isset($cryptoInfo['USD']['FROMSYMBOL'])) {
// log or do whatever to handle error here
echo "no path [USD][FROMSYMBOL] found for crypto: " . $cryptoSymbol . PHP_EOL;
continue;
}
// Symbol in on your json path/array [USD][FROMSYMBOL]
$thisCoinSymbol = $cryptoInfo['USD']['FROMSYMBOL'];
$coinHeld = array_key_exists($thisCoinSymbol, $myCoins);
// Only retour held
if ( !$coinHeld ) { continue; }
// get price:
$thisCoinPrice = $cryptoInfo['USD']['PRICE'];
// get symbol holding:
if ($coinHeld) {
$myBalance_units = $myCoins[$thisCoinSymbol]['balance'];
}
// calculate total holdings:
if ($coinHeld) {
$myBalance_USD = $myBalance_units * $thisCoinPrice;
$portfolioValue += $myBalance_USD;
}
}
}
echo '<br>';
echo $email_array[$i];
echo $portfolioValue . PHP_EOL;
echo '<br>';
echo '<br>';
$portfolioValue = 0;
}
?>
Sidenote: Learn about prepared statement because right now your query is susceptible to SQL injection attack. Also see how you can prevent SQL injection in PHP.

Compare uploaded data in database and raw CSV data

Here is the code after I uploaded the raw file then tried to validate the raw file with the uploaded file to see if they match:
while ($db_fetch_row = sqlsrv_fetch_array($database_query)){
$db_eid = $db_fetch_row['eid'];
$db_team_lead = $db_fetch_row['team_lead'];
$db_role = $db_fetch_row['role'];
$db_productivity = $db_fetch_row['productivity'];
$db_quality = $db_fetch_row['quality'];
$db_assessment = $db_fetch_row['assessment'];
$db_staffed_hours = $db_fetch_row['staffed_hours'];
$db_kpi_productivity = $db_fetch_row['kpi_productivity'];
$db_kpi_quality = $db_fetch_row['kpi_quality'];
$db_kpi_assessment = $db_fetch_row['kpi_assessment'];
$db_kpi_staffed_hours = $db_fetch_row['kpi_staffed_hours'];
for($row = 2; $row <= $lastRow; $row++) {
$eid = $worksheet->getCell('A'.$row)->getValue();
$team_lead = $worksheet->getCell('C'.$row)->getValue();
$role = $worksheet->getCell('B'.$row)->getValue();
$productivity = $worksheet->getCell('D'.$row)->getValue();
$productivity1 = chop($productivity,"%");
$quality = $worksheet->getCell('E'.$row)->getValue();
$quality1 = chop($quality,"%");
$assessment = $worksheet->getCell('F'.$row)->getValue();
$assessment1 = chop($assessment,"%");
$staffed_hours = $worksheet->getCell('G'.$row)->getValue();
$staffed_hours1 = chop($staffed_hours,"%");
$kpi_productivity = $worksheet->getCell('H'.$row)->getValue();
$kpi_quality = $worksheet->getCell('I'.$row)->getValue();
$kpi_assessment = $worksheet->getCell('J'.$row)->getValue();
$kpi_staffed_hours = $worksheet->getCell('K'.$row)->getValue();
if($db_eid == $eid) {
echo "Raw and Uploaded file Matched";
} else {
echo "Did not match";
}
}
}
The output always didn't match, as you can see below:
Of course it outputs that. Let's think it through:
For every row in the DB, you are checking EVERY row in the CSV. Presumably there is only ONE row in the CSV that has the same ID as the row in the DB, so that means if there are 100 records in the CSV, it will output "no match" 99 times (assuming there is 1 record in the CSV that does match).
One approach is to separate it into a function and attempt to find the matching row, as follows:
// Loop over all DB records
while ($db_fetch_row = sqlsrv_fetch_array($database_query)) {
// call our new function to attempt to find a match
$match = find_matching_row( $db_fetch_row, $worksheet );
// If there's no match, output "didn't find a match"
if ( ! $match ) {
echo '<br>DID NOT FIND A MATCH.';
// If there IS a match, $match represents the row number to use....
} else {
var_dump( $match );
// Do your work on the match data...
$team_lead = $worksheet->getCell('C'.$match)->getValue();
// ...etc
}
}
/**
* Attempt to find a row from the CSV with the same ID as the DB
* record passed in.
*
* #param array $db_fetch_row
* #param mixed $worksheet
*/
function find_matching_row( $db_fetch_row, $worksheet ) {
$db_eid = $db_fetch_row['eid'];
// Youll need to calculate $lastRow for this to work right..
$lastRow = .... ;
// Loop through the CSV records
for($row = 2; $row <= $lastRow; $row++) {
// If the IDs match, return the row number
if($db_eid == $worksheet->getCell('A'.$row)->getValue() ){
return $row;
}
}
// If no match, return FALSE
return FALSE;
}

Is there a way to run PHP long loop code faster?

I have a code that runs a query on an external (slow) API and loops through a lot of variables and inserts data, sends email, ect'.
This is the main function as an example:
// MAIN: Cron Job Function
public function kas_alert() {
// 0. Deletes all the saved data from the `data` table 1 month+ ago.
// $this->kas_model->clean_old_rows();
// 1. Get 'prod' table
$data['table'] = $this->kas_model->prod_table();
// 2. Go through each row -
foreach ( $data['table'] as $row ) {
// 2.2. Gets all vars from the first query.
$last_row_query = $this->kas_model->get_last_row_of_tag($row->tag_id);
$last_row = $last_row_query[0];
$l_aaa_id = $last_row->prod_aaa_id;
$l_and_id = $last_row->prod_bbb_id;
$l_r_aaa = $last_row->dat_data1_aaa;
$l_r_and = $last_row->dat_data1_bbb;
$l_t_aaa = $last_row->dat_data2_aaa;
$l_t_and = $last_row->dat_data2_bbb;
$tagword = $last_row->tag_word;
$tag_id = $last_row->tag_id;
$country = $last_row->kay_country;
$email = $last_row->u_email;
$prod_name = $last_row->prod_name;
// For the Weekly report:
$prod_id = $last_row->prod_id;
$today = date('Y-m-d');
// 2.3. Run the tagword query again for today on each one of the tags and insert to DB.
if ( ($l_aaa_id != 0) || ( !empty($l_aaa_id) ) ) {
$aaa_data_today = $this->get_data1_aaa_by_id_and_kw($l_aaa_id, $tagword, $country);
} else{
$aaa_data_today['data1'] = 0;
$aaa_data_today['data2'] = 0;
$aaa_data_today['data3'] = 0;
}
if ( ($l_and_id != 0) || ( !empty($l_and_id) ) ) {
$bbb_data_today = $this->get_data1_bbb_by_id_and_kw($l_and_id, $tagword, $country);
} else {
$bbb_data_today['data1'] = 0;
$bbb_data_today['data2'] = 0;
$bbb_data_today['data3'] = 0;
}
// 2.4. Insert the new variables to the "data" table.
if ($this->kas_model->insert_new_tag_to_db( $tag_id, $aaa_data_today['data1'], $bbb_data_today['data1'], $aaa_data_today['data2'], $bbb_data_today['data2'], $aaa_data_today['data3'], $bbb_data_today['data3']) ){
}
// Kas Alert Outputs ($SEND is echoed in it's original function)
echo "<h1>prod Name: $prod_id</h1>";
echo "<h2>tag id: $tag_id</h2>";
var_dump($aaa_data_today);
echo "aaa old: ";
echo $l_r_aaa;
echo "<br> aaa new: ";
echo $aaa_data_today['data1'];
var_dump($bbb_data_today);
echo "<br> bbb old: ";
echo $l_r_and;
echo "<br> bbb new: ";
echo $bbb_data_today['data1'];
// 2.5. Check if there is a need to send something
$send = $this->check_if_send($l_aaa_id, $l_and_id, $l_r_aaa, $aaa_data_today['data1'], $l_r_and, $bbb_data_today['data1']);
// 2.6. If there is a trigger, send the email!
if ($send) {
$this->send_mail($l_aaa_id, $l_and_id, $aaa_data_today['data1'], $bbb_data_today['data1'], $l_r_aaa, $l_r_and, $tagword, $email, $prod_name);
}
}
}
This CodeIgniter controller is runs every day and I get this running (Cronjob) for too long using almost nothing from the CPU and RAM (RAM is at 400M/4.25G and CPU at ONLY 0.7%-1.3%).
I wonder if there's an option to split all foreach loops to smaller threads (and I'm not sure if forking will do here) and run all the foreach loops in parallel but in a way that it wont get my server crashing.
I'm no DevOps and really interested learning - What should I do in this case?

Foreach loop full execution and stop the rest of the script

I have a product table from where I am checking that quantity for respective product id(s) is valid or not..
this is the code snippet :
$pids = explode(',',$pid); /*in the form of 2,3,4.....*/ /*$pid->product_id*/
$q = explode(',',$q_total); /*in the form of 2,3,4.....*/ /*$q->quantity*/
/*checking start*/
foreach($pids as $index => $ps){
$quants = $q[$index];
$sql = $stsp->query("SELECT quantity FROM product WHERE id='$ps'");
$row = $sql->fetch(PDO::FETCH_ASSOC);
$quantity_rem = $row['quantity'];
if($quants > $quantity_rem){
$array = array();
$array['errquant'] = 'wrong_quant';
$array['error_pr'] = $ps;
echo json_encode($array);
exit; /*stop the rest of the code from executing*/
}
}
/*rest of the code outside the loop*/
So here what is happening is it checks the quantity ($quantity_rem) from table of a product id and if that quantity is less than the quantity given ($q), then the script stops and echo the product id..
But I have more that 1 product .. It's not checking the rest since whenever there is a fault it stops and echo out. I want to check all the products and echo out the product id(s) and stop the rest of the script outside the loop..
Help needed!
Thanks.
and please don't talk to me about sql injection because i know it is vulnerable and i will take care of that..
Try this:
$pids = explode(',',$pid); /*in the form of 2,3,4.....*/ /*$pid->product_id*/
$q = explode(',',$q_total); /*in the form of 2,3,4.....*/ /*$q->quantity*/
/*checking start*/
$errors = array();
foreach($pids as $index => $ps){
$quants = $q[$index];
$sql = $stsp->query("SELECT quantity FROM product WHERE id='$ps'");
$row = $sql->fetch(PDO::FETCH_ASSOC);
$quantity_rem = $row['quantity'];
if($quants > $quantity_rem){
$array = array();
$array['errquant'] = 'wrong_quant';
$array['error_pr'] = $ps;
$errors[] = $array;
}
}
echo json_encode($errors);
foreach($pids as $index => $ps){
$quants = $q[$index];
$sql = $stsp->query("SELECT quantity FROM product WHERE id='$ps'");
$row = $sql->fetch(PDO::FETCH_ASSOC);
$quantity_rem = $row['quantity'];
$array = array();
if($quants > $quantity_rem){
$array[$ps]['errquant'] = 'wrong_quant';
// note little change - you will get array with product ids as key
//and qty error assigned to them
}
echo json_encode($array);
exit; /*stop the rest of the code from executing*/

php code of troubling getting multiple value

I have codes that should be getting value from mysql database, I can get only one value but I have while loop so it can get value and output data separated with comma. But I only get one value and cannot get multiple value. the result should be like this, // End main PHP block. Data looks like this: [ [123456789, 20.9],[1234654321, 22.1] ] here is the code:
<?php
// connect to MySQL
mysql_connect('localhost','','') or die("Can't connect that way!");
#mysql_select_db('temperature1') or die("Unable to select a database called 'temperature'");
if(ISSET($_GET['t']) && (is_numeric($_GET['t'])) ){
// message from the Arduino
$temp = $_GET['t'];
$qry = "INSERT INTO tempArray(timing,temp) VALUES(".time().",'$temp')";
echo $qry;
mysql_query($qry);
mysql_close();
exit('200');
}
// no temp reading has been passed, lets show the chart.
$daysec = 60*60*24; //86,400
$daynow = time();
if(!$_GET['d'] || !is_numeric($_GET['d'])){
$dayoffset = 1;
} else {
$dayoffset = $_GET['d'];
}
$dlimit = $daynow-($daysec*$dayoffset);
$qryd = "SELECT id, timing, temp FROM tempArray WHERE timing>='$dlimit' ORDER BY id ASC LIMIT 1008";
// 1008 is a weeks worth of data,
// assuming 10 min intervals
$r = mysql_query($qryd);
$count = mysql_num_rows($r);
$i=0;
$r = mysql_query($qryd);
$count = mysql_num_rows($r);
while($row=mysql_fetch_array($r, MYSQL_ASSOC)) {
$tid=$row['id'];
$dt = ($row['timing']+36000)*1000;
$te = $row['temp'];
if($te>$maxtemp) $maxtemp=$te; // so the graph doesnt run along the top
if($te<$mintemp) $mintemp=$te; // or bottom of the axis
$return="[$dt, $te]";
echo $return; //here I get all values [1385435831000, 21][1385435862000, 23][1385435892000, 22][1385435923000, 25][1385435923000, 22]
$i++;
if($i<$count) $return= ","; echo $return; // if there is more data, add a ',' however, it return me ,,,[1385435923000, 22]
$latest = "$dt|$te"; // this will get filled up with each one
}
mysql_close();
// convert $latest to actual date - easier to do it here than in javascript (which I loathe)
$latest = explode('|',$latest);
$latest[0] = date('g:ia, j.m.Y',(($latest[0])/1000)-36000);
?>
You're just assigning $return to the values from the last row your while loop grabbed instead of concatenating it. Try this
$return = "[";
while($row=mysql_fetch_array($r, MYSQL_ASSOC)) {
$tid=$row['id'];
$dt = ($row['timing']+36000)*1000;
$te = $row['temp'];
if($te>$maxtemp) $maxtemp=$te; // so the graph doesnt run along the top
if($te<$mintemp) $mintemp=$te; // or bottom of the axis
$return.="[$dt, $te]";
$i++;
if($i<$count) $return .= ", ";// if there is more data, add a ','
$latest = "$dt|$te"; // this will get filled up with each one
}
$return .= "]";

Categories