PHP: A string, two arrays and 4 loops result in a 0 - php

In my android app user can upload up to 5 images for an item they have in their collection.
This is what my android app java code is sending over to the PHP server via POST:
[user_id=83,
item_id=24,
item_number_of_photos=1,
item_image_filename_0=http://www.asdqwe.net/item_images/83_image_2014-02-07-16-44-12.jpg,
item_image_description_0=mouse]
This is the PHP Code that handles it:
if (!empty($_POST)) {
$user_id = $_POST["user_id"];
$item_id = $_POST["item_id"];
$item_number_of_photos = $_POST['item_number_of_photos'];
for ($x=0; $x<$item_number_of_photos; $x++) {
if(isset($_POST['item_image_filename_'.$x]) && !empty($_POST['item_image_filename_'.$x])) {
$item_image_filenames[$x] = $_POST['item_image_filename_'.$x];
}
if(isset($_POST['item_image_description_'.$x]) && !empty($_POST['item_image_description_'.$x])) {
$item_image_descriptions[$x] = $_POST['item_image_description_'.$x];
}
}
$query_add_item_photos = "INSERT INTO
product_photos (
product_id,
product_photo,
product_photo_added_by_user,
product_photo_description
)";
////////////////////////////////////////////////////////////
////ADD THE PHOTOS TO THE PHOTOS TABLE//////////////////////
////////////////////////////////////////////////////////////
try {
for($x = 0; $x<$item_number_of_photos; $x++) {
$query_add_item_photos+= " VALUES
(
:product_id,
:product_photo_filename_" . $x .",
:product_photo_added_by_user,
:product_photo_description_" . $x . "
)";
}
$input_parameters = array(
':product_id' => $item_id,
':product_photo_added_by_user' => $user_id,
);
for($x = 0; $x<$item_number_of_photos; $x++) {
$input_parameters[':product_photo_filename_' . $x] = $item_image_filenames[$x];
$input_parameters[':product_photo_description_' . $x] = $item_image_descriptions[$x];
}
$sth = $connection->prepare($query_add_item_photos);
$sth->execute($input_parameters);
} catch(PDOException $pe) {
$response["success"] = $http_response_server_error;
$response["message"] = $http_response_server_error . $pe . $query_add_item_photos;
die(json_encode($response));
}
$response["success"] = $http_response_success;
$response["message"] = "WE MADE IT";
die(json_encode($response));
$connection = null;
} else {
$response["success"] = $http_response_bad_request;
$response["message"] = $http_message_bad_request;
die(json_encode($response));
$connection = null;
}
At the end when I run this, I get a PDO error saying that the query = "0".
I have only basic understanding of PHP so this is huge pain for me

Local Variables Issue
In your for loop, you are assigning values to $item_image_filenames[$x] array element and also to $item_image_descriptions[$x] array element.
for ($x=0; $x<$item_number_of_photos; $x++) {
...
$item_image_filenames[$x] = $_POST['item_image_filename_'.$x];
...
$item_image_descriptions[$x] = $_POST['item_image_description_'.$x];
}
But (assuming you have posted all of your code), these 2 arrays fall out of scope and disappear as soon as you exit your for loop. They weren't defined before your for loop, which means that they are being defined local to your for loop.
The result of this is that, later, when you attempt to reference these arrays, they don't exist, and they have no values. So, later on in your code...
for($x = 0; $x<$item_number_of_photos; $x++) {
$input_parameters[':product_photo_filename_' . $x] = $item_image_filenames[$x];
$input_parameters[':product_photo_description_' . $x] = $item_image_descriptions[$x];
}
... is going to result in assigning to $input_parameters values that don't exist.
To solve this problem, define $item_image_filenames and $item_image_descriptions before you enter your for loop. This way, they will continue to exist inside and after your for loop. You can do this:
$user_id = $_POST["user_id"];
$item_id = $_POST["item_id"];
$item_number_of_photos = $_POST['item_number_of_photos'];
// Define empty arrays so that I can use them throughout my code.
$item_image_filenames = array();
$item_image_descriptions = array();
for ($x=0; $x<$item_number_of_photos; $x++) {
...
String Concatenation Syntax
I also noticed that your line of code:
$query_add_item_photos+= " VALUES
...
... is not the correct way to do string concatenation in PHP. You want to use .= instead of +=. In PHP, strings are concatenated with ., as in the example: $string1 = $string2 . $string3;
Your code should instead be:
$query_add_item_photos .= " VALUES
...

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.

Capture successfully inserted records into array

I am using PDO to insert records from one table into another.
I'm trying to capture the records that were successfully inserted into the other table, while also capturing the records that might have failed to insert.
<?php
$checkcontainer = $_POST['checkcontainer'];
$checkscac = $_POST['checkscac'];
$comment = $_POST['comment'];
$time = date('Y-m-d H:i:s');
$containerSuccess = array();
$containerFail = array();
$count = count($checkcontainer);
for($i = 0; $i < $count; $i++)
{
$container = $checkcontainer[$i];
$scac = $checkscac[$i];
$insert = $dbc->prepare("INSERT IGNORE INTO trucker_edi_comms (container, scac, fac_comments, fac_datestamp) VALUES (:ucont,:uscac,:ucomm,:utime);");
$insert->execute([
'ucont' => $container,
'uscac' => $scac,
'ucomm' => $comment,
'utime' => $time
]);
if($insert)
{
$containerSuccess = $container;
//echo "containers saved: " . $containerSuccess;
}
else
{
$containerFail = $container;
//echo "containers failed: " . $containerFail;
}
}
echo "containers saved: " . $containerSuccess;
?>
The INSERT statement works. I can also set the $containerSuccess array to $container. If 3 containers are successfully inserted, the output from inside the FOR loop looks like this:
containers saved: TEST123456789containers saved: TEST98642357containers saved: TEST65897531
But I need to be able to echo $containerSuccess outside of the FOR loop. Currently, the output looks like this:
containers saved: TEST65897531
I'm only able to grab the last container that was saved.
I need to echo out all of the containers outside of the FOR loop to display to the user.
How can I make this happen?
Your example was trying to populate a declared array with a string, so you were on the right track concerning the variable type. You can populate an array for outputting the saved/failed containers after the loop completes, and if you want it to output on one line, use implode() for the output:
<?php
$checkcontainer = $_POST['checkcontainer'];
$checkscac = $_POST['checkscac'];
$comment = $_POST['comment'];
$time = date('Y-m-d H:i:s');
$containerSuccess = array();
$containerFail = array();
$count = count($checkcontainer);
for($i = 0; $i < $count; $i++)
{
$container = $checkcontainer[$i];
$scac = $checkscac[$i];
$insert = $dbc->prepare("INSERT IGNORE INTO trucker_edi_comms (container, scac, fac_comments, fac_datestamp) VALUES (:ucont,:uscac,:ucomm,:utime);");
$insert->execute([
'ucont' => $container,
'uscac' => $scac,
'ucomm' => $comment,
'utime' => $time
]);
if($insert)
$containerSuccess[] = $container;
else
$containerFail[] = $container;
}
echo "containers saved: " . implode(', ', $containerSuccess);
echo "containers failed: " . implode(', ', $containerFail);
?>

How to sequentially push into array from MYSQL query?

The php and js are the following:
createRoomTable()
function createRoomTable(){
$.post('../include/returnRoomTable.php',{
//nothing to transmit
}).then((returnedTableMarkup) => {
returnedTableMarkup = JSON.parse(returnedTableMarkup)
console.log("data from returnRoomTable.php is ", returnedTableMarkup)
//$('#roomTableOutput').html(returnedTableMarkup)
})
}
<?php
session_start();
try{
$connection = new PDO('mysql:host=localhost;dbname=XXXX',
'XXXX','XXXXXX');
}catch(PDOException $e){
echo $e->getMessage();
}
$allRooms = $connection->query("
SELECT name
FROM raum
")->fetchAll(PDO::FETCH_NUM);
$indexLimit = count($allRooms);
$allSeats = [];
for($index = 0; $index < $indexLimit; $index++){
$allSeats = array_push($connection->query("
SELECT nummer
FROM arbeitsplatz
WHERE raum = '".$allRooms[$index]."'
")->fetchAll(PDO::FETCH_NUM));
}
echo json_encode ($allSeats);
?>
So currently, consolelog says the array is "null".
What I need is a flexible, two-dimensional array ("$allSeats") which takes each iteration from the MYSQL query and puts it into this array.
The problem is that I'm not very experiences with arrays in php, and I'm out of ideas how I can accomplish this.
Okay, so I found a solution to my problem myself:
The php now looks like this:
<?php
session_start();
try{
$connection = new PDO('mysql:host=localhost;dbname=arbeitsplatzverwaltung',
'verwalter','N7pY1OTl2gaBbc51');
}catch(PDOException $e){
echo $e->getMessage();
}
$allRooms = $connection->query("
SELECT name
FROM raum
")->fetchAll(PDO::FETCH_NUM);
$indexLimit = count($allRooms);
$allSeats = [];
for($index = 0; $index < $indexLimit; $index++){
$currentQuery = $connection->query("
SELECT nummer
FROM arbeitsplatz
WHERE raum = '".$allRooms[$index][0]."'
")->fetchAll(PDO::FETCH_NUM);
array_push($allSeats, $currentQuery);
}
/*
$allSeats[] = $connection->query("
SELECT nummer
FROM arbeitsplatz WHERE raum = '".$allRooms[$index]."'
")->fetchAll(PDO::FETCH_NUM);*/
echo json_encode ($allSeats);
?>
And when I output this in my JS, I get an array of arrays containing the values.

How to get attribute values of an object stored in $_SESSION?

I have this code that store a "student" object in $_SESSION:
if(isset($_POST["name"]) && isset($_POST["note"]) && isset($_POST["year"]))
{
$nom = $_POST["name"];
$note = $_POST["note"];
$session = $_POST["year"];
$vec = array("name" => $name, "note" => $note, "year" => $year);
$_SESSION["students"][] = $vec;
echo "The student has been added.<br><br>";
}
Then I have this code in another page:
function calculateAverage()
{
$av = 0;
$count = 0;
foreach($_SESSION['students'] as $student)
{
$av = $av + $student["note"];
$count = $count + 1;
}
return $av / $count;
}
function bestNote()
{
//$best = array_search(max())
return $best;
}
function worstNote()
{
$worst = min(array_search(["note"], $_SESSION['students']));
return $worst;
}
if(isset($_SESSION['students']))
{
echo "The average note of the group is = " . calculateAverage() . "\n";
echo "The one with the best note is " . bestNote()["name"] . " is " . hauteNote()["note"] . " points.\n";
echo "The one with the worst note is " . worstNote()["name"] . " with " . basseNote()["note"] . " points.\n";
}
As you can see, it is not finished. What I want to do is to be able to get the note of a student that is stored in $_SESSION["students"]. How can I do this?
Thanks for answers.
you can access the stored values within a nested array like so:
$studentNote = $_SESSION["students"][YourActiveStudent]["note"];
However, you are currently not adding but overwriting data. Use array_push() to add data to an array (your students).
And when adding a student to the array, make sure to give it a name to make it associative so you can simply "call a student":
$_SESSION["students"][$nom] = $vec;
this way, if the $nom was "Max", you could say
$_SESSION["students"]["Max"]["note"]
to get Max's note (BTW, I assume you are talking about grades or marks, rather than notes?)

PHP $_POST Validation

Is there a quick and easy way to check if any of my $_POST data has the same value?
I need it as a conditional statement...
Example:
$week1 = $_POST['Week_1'];
$week2 = $_POST['Week_2'];
$week3 = $_POST['Week_3'];
$week4 = $_POST['Week_4'];
$week5 = $_POST['Week_5'];
$week6 = $_POST['Week_6'];
$week7 = $_POST['Week_7'];
$week8 = $_POST['Week_8'];
$week9 = $_POST['Week_9'];
$week10 = $_POST['Week_10'];
$week11 = $_POST['Week_11'];
$week12 = $_POST['Week_12'];
$week13 = $_POST['Week_13'];
$week14 = $_POST['Week_14'];
$week15 = $_POST['Week_15'];
$week16 = $_POST['Week_16'];
$week17 = $_POST['Week_17'];
If the values of any of the weeks = equal the value of any of the other weeks, error...
Is there a quick way to do this in PHP?
Thanks!
Chris
first though to pop in to my head:
$r=array_unique(array($week1, ...));
if (count($r) !=17){
//error
}
If the only $_POST values you have are 'Week_1' through 'Week_17' then
if (count(array_unique($_POST)) === count($_POST)) {
//all unique values, do stuff...
}
Just loop through the pairs and compare them:
$weeks=array();
foreach(range(1,17) as $i)
{
array_push($weeks,'Week_' . $i);
}
foreach(range(1,16) as $i)
{
foreach(range($i+1,17) as $j)
{
if($_POST[$weeks[$i]]==$_POST[$weeks[$j]])
{
die("Rut-roh!");
{
}
}
}

Categories