I have this script executing as a cron job everyday to update days remaining to pay invoices. I first query every row of my table and attempt to store the data in a multidimensional array but this seems to be storing everything I query in the first element of my array.
Here's my script:
<?php
include '../inc/dbinfo.inc';
ini_set("log_errors", 1);
ini_set("error_log", "/tmp/php-error.log");
error_log( "################################################# UpdateVendorInvoiceDays.php #################################################" );
$three = 3;
$fetchAllInvoices = "SELECT VENDORINVOICEID, VdrInvoiceReceived, PaymentDue, COUNT(*), DATEDIFF(PaymentDue, NOW()) FROM tblVendorInvoices WHERE VdrInvoiceStatusID != ?";
$getInvoices = $conn->prepare($fetchAllInvoices);
$getInvoices->bind_param("i", $three);
$getInvoices->execute();
$result = $getInvoices->get_result();
$rows = array();
$j = 0;
while($row = $result->fetch_assoc())
{
$rows[$j][] = $row;
$j++;
}
echo json_encode($rows[0][0]); //Only outputs one row
//UPDATE DAYS REMAINING IN EACH ENTRY THAT ISNT PAID
$updateDaysRemaining = "UPDATE tblVendorInvoices SET DaysRemaining = ? WHERE VENDORINVOICEID = ? AND VdrInvoiceStatusID ! = ?";
$setDays = $conn->prepare($updateDaysRemaining);
$k = 0; //incrementor
$numberOfEntries = $rows['COUNT(*)'];
for($k;$k<$numberOfEntries;$k++){
$setDays->bind_param("iii", $rows[$k]["DATEDIFF(PaymentDue, NOW())"],
$rows[$k]['VENDORINVOICEID'], $three);
if($setDays->execute()){
error_log('Cron success');
}else{
error_log('Cron fail');
}
}
?>
Currently the output from my first query is:
[[{"VENDORINVOICEID":88,"VdrInvoiceReceived":"2018-08-21","PaymentDue":"2018-07-27","COUNT(*)":2,"DATEDIFF(PaymentDue, NOW())":-25}]]
and my error log only gives me a notice for $rows['COUNT(*)'] being undefined (which makes sense)
I've looked at other answers here but they don't seem to have the same structure as I do.
EDIT: I also have 2 rows in my database but this only puts out one. I forgot to mention this.
There are a couple of simplifications to get all of the rows. Instead of...
while($row = $result->fetch_assoc())
{
$rows[$j][] = $row;
$j++;
}
echo json_encode($rows[0][0]);
You can just return all rows using fetch_all()...
$rows = $result->fetch_all (MYSQLI_ASSOC);
echo json_encode($rows);
Then encode the whole array and not just the one element - which is what $rows[0][0] was showing you.
As for you other problem - change in your select statement to
COUNT(*) as rowCount
and then you can use this alias for the field reference...
$rows['COUNT(*)']
becomes
$rows['rowCount']
Related
How to assign value to an array in while loop in php from mysqli result to make a counter to filter another while loop??
I want to assign something like this for my counter variable:
$counter = array("6:00 Am" => 0, "8:00 Am" => 0, "10:00 Am" => 0);
For this code:
//This is from transaction table
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($res2);
while($rows5 = $res2->fetch_assoc())
{
//Not working
$counter[] = array($rows5['tr_sched'] => 0)
}
So I can filter this another while loop if the schedule time is greater than to my limit variable, like this:
//This is from my schedule table
$stm = "SELECT sc_time FROM schedule GROUP BY sc_time";
$res = $conn->query($stm);
$counter = array();
while($row4 = $res4->fetch_assoc())
{
//Note working
if($counter[$row4['sc_time']] >= $limit/*=10*/)
{
echo "<option disabled="">" . $row4['sc_time'] . "</option>";
}
else
{
echo "<option>" . $row4['sc_time'] . "</option>";
}
}
The goal of all the codes above is to display all schedule time from schedule table as an option for select element and if the schedule time is already have a 10 records or greater than(limit variable) on my transaction table for today it will display as option but disable so it can't be selected by user.
I hope you get what I mean, I will try to keep active to answer if you have something to clarify about my question.
You don't need the while loop at all.
You can use array functions to populate the array with static values.
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($stm2);
// get values from a single column
$keys = array_column($res2->fetch_all(MYSQLI_ASSOC), 'tr_sched');
// create an array with all values as 0 and keys from $keys
$counter = array_fill_keys($keys, 0);
Of course, don't reset the array later on with $counter = array();
If you want to loop anyway, then you can use a simple foreach loop.
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($stm2);
foreach($res2 as $rows5) {
$counter[$rows5['tr_sched']] = 0;
}
I have a database where each row contains a unique userid number, and a referralid number that links them to the person that referred them to the site. I am trying to create a recursive function that will search the database as long as it continues to find users, and perform several calculations as it goes. Below is what I have so far - I am getting stuck on trying to create incrementing query variables - PLEASE HELP!
function findrepsloop($refidnum, $num){
echo "FINDREPSLOOP STARTED<br><br>";
if(strlen($refidnum) > 0){
echo "FIRST STRLEN IF LOOP PASSED: $refidnum<br><br>";
$totalreps++;
$query{$num} = "SELECT * FROM user WHERE (refidnum = '$refidnum' && active = 'YES') ";
$result{$num} = mysql_query($query{$num});
$line{$num} = mysql_fetch_array($result{$num}, MYSQL_NUM);
$total{$num} = mysql_num_rows($result{$num});
echo "QUERY $num found $total{$num} rows in the database. LINE 0: '$line{$num}[0]<br><br>";
$totaltemp = 0;
if($total{$num} > 2){ $totaltemp = $total{$num} / 3; $totaltemp = floor($totaltemp); }else{}
$numberofthrees = $numberofthrees + $totaltemp;
while(strlen($line{$num}[0]) > 0){
$refidnum = $line{$num}[0];
$num++;
findrepsloop($refidnum, $num);
$line{$num} = mysql_fetch_array($result{$num}, MYSQL_NUM);
}
}else{
}
}
Hi I'm currently querying from a database base user ids for a contest, However I want to avoid choosing duplicates in my results_array, this function getrandomspecies receives a array_result, this array results iterates 7 times. How test that I don't put duplicates in my results_array? I have gotten several duplicates.
function getrandomspecies($array_result){
//database connection
$dbn = adodbConnect();
foreach($array_result as $possible){
//query the results
$querys= "select * from taxonomic_units where tsn = $possible";
$resultss = $dbn -> Execute($querys);
while($rowss=$resultss->FetchRow()){
$id = $rowss['tsn']; //there ID
$ranksss = $rowss['rank_id']; //ranking id, I choose 220 and 230
if($ranksss == 220 || $ranksss == 230){
$prelimary_array[] = $id;
}
}
//grab random index
$index = array_rand($prelimary_array,1);
//put result id into a variable
$newspecies = $prelimary_array[$index];
//put that variable in an array
$results_array[] = $newspecies; //there is 7 newspecies/winners at the end, I dont want duplicates
}
return $results_array;
}
MySQL should be the following :
select distinct tsn, rank_id from taxonomic_units where tsn = $possible
But you should ideally use prepared statements.
what about this? You may do it with one query:
$querys= "select DISTINCT tsn from taxonomic_units where tsn IN (".implode(",",$array_result).") AND rank_id IN (220,230) ORDER BY RAND() LIMIT 7 ";
Loop your result array and if it does not exists add it. If you end up with less than 7, do your big loop again.
replace this line :
$results_array[] = $newspecies;
by:
$loop_1_more_time=0;
if (isset($results_array)){
foreach($results_array as $result){
if ($result == $new_specie){
$loop_1_more_time=1;
}
}
}
if ($loop_1_more_time == 0){
$results_array[] = $newspecies;
}
//there, if $loop_1_more_time equals 1, start again. To start again and be sure you have seven instead of 6 or less, You could replace your big first "foreach" loop with a "for" loop that depends of the count() of the $array_result, and the $array_result would be array_result[$i] instead of $possible. $i would start at 0 and increment at each end of loop. It would not be incremented if $loop_1_more_time==1;.
Example :
for ($i = 0; $i < count($array_result); $i++) {
//stuff
//if ($loop_1_more_time=1;) { $i--; }
}
Why don't you try shuffling the array, and then picking the first X numbers?
That way, rather than having to check the results array for duplicates, it will never come up in the first place
I previously designed the website I'm working on so that I'd just query the database for the information I needed per-page, but after implementing a feature that required every cell from every table on every page (oh boy), I realized for optimization purposes I should combine it into a single large database query and throw each table into an array, thus cutting down on SQL calls.
The problem comes in where I want this array to include skipped IDs (primary key) in the database. I'll try and avoid having missing rows/IDs of course, but I won't be managing this data and I want the system to be smart enough to account for any problems like this.
My method starts off simple enough:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Two notes:
Yes, I should probably move that $localityMax check to a PHP loop.
I'm intentionally skipping the first array key.
The problem here is that any missed key in the database isn't accounted for, so it ends up outputting like this (sample table):
1 - Tok
2 - Juneau
3 - Anchorage
4 - Nashville
7 - Chattanooga
8 - Memphis
-
-
I want to write "Error" or NULL or something when the row isn't found, then continue on without interrupting things. I've found I can check if $i is less than $row[$i] to see if the row was skipped, but I'm not sure how to correct it at that point.
I can provide more information or a sample database dump if needed. I've just been stuck on this problem for hours and hours, nothing I've tried is working. I would really appreciate your assistance, and general feedback if I'm making any terrible mistakes. Thank you!
Edit: I've solved it! First, iterate through the array to set a NULL value or "Error" message. Then, in the assignations, set $i to $row["id"] right after the mysql_fetch_assoc() call. The full code looks like this:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Reset
for ($i=1;$i<$localityMax+1;$i++)
{
$localityData["id"][$i] = NULL;
$localityData["name"][$i] = "Error";
}
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$i = $row["id"];
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Thanks for the help all!
Primary keys must be unique in MySQL, so you would get a maximum of one possible blank ID since MySQL would not allow duplicate data to be inserted.
If you were working with a column that is not a primary or unique key, your query would need to be the only thing that would change:
SELECT id, name FROM localities WHERE id != "";
or
SELECT id, name FROM localities WHERE NOT ISNULL(id);
EDIT: Created a new answer based on clarification from OP.
If you have a numeric sequence that you want to keep unbroken, and there may be missing rows from the database table, you can use the following (simple) code to give you what you need. Using the same method, your $i = ... could actually be set to the first ID in the sequence from the DB if you don't want to start at ID: 1.
$result = mysql_query('SELECT id, name FROM localities ORDER BY id');
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[(int) $row['id']] = array(
'id' => $row['id'],
'name' => $row['name'],
);
}
// This saves a query to the database and a second for loop.
end($data); // move the internal pointer to the end of the array
$max = key($data); // fetch the key of the item the internal pointer is set to
for ($i = 1; $i < $max + 1; $i++) {
if (!isset($data[$i])) {
$data[$i] = array(
'id' => NULL,
'name' => 'Erorr: Missing',
);
}
echo "$i. {$data[$id]['id']} - {$data[$id]['name']}<br />\n";
}
After you've gotten your $localityResult, you could put all of the id's in an array, then before you echo $localityDataStuff, check to see
if(in_array($i, $your_locality_id_array)) {
// do your echoing
} else {
// echo your not found message
}
To make $your_locality_id_array:
$locality_id_array = array();
foreach($localityResult as $locality) {
$locality_id_array[] = $locality['id'];
}
this is the code i use to generate single json object
$SQL = mysql_query("SELECT * FROM `receipts` WHERE DATE(date) = '2011-08-03'");
if(mysql_num_rows($SQL ) > 0){
$i=0;
$responce->success = true;
while($SQL_RESULT = mysql_fetch_object($SQL)){
$responce->data[$i]['reciept_no'] = $SQL_RESULT->reciept_no;
$responce->data[$i]['time'] = $SQL_RESULT->date;
$responce->data[$i]['user'] = $SQL_RESULT->user;
$i++;
}
}
else{
$responce->success = false;
$responce->data = '';
$responce->reason = "No Activity...";
}
echo json_encode($responce);
result is like
{"success":true,"data":[{"reciept_no":"2411","time":"09:33:56 AM","user":"test"},
{"reciept_no":"2412","time":"11:29:01 AM","user":" test "}]}
so there is another query which similar to this and generate exact same kind of output but from a another mysql table
i want to do is combine two results and send to javascript then decode it in javascript
like wrap first result with like table1 second result with table 2 or something
how to do that?
Sorry for the bad English
Regards
You could run both queries, one outputs to $response1 and the other to $response2, then you can use:
echo json_encode(array('table1'=>$response1,'table2'=>$response2));
JSON is just a text representation of a data structure. If you want to store two separate results in a single structure, then do
data['response #1'] = 'blah blah blah';
data['response #2'] = 'other other other';
You could store the two queries' data into a single sub-array, but then you'd need some extra data to be able to differentiate betweeen the two data sources. "did this record come from query #1? or from query #2?"
$SQL = mysql_query("SELECT * FROM `receipts` WHERE DATE(date) = '2011-08-03'");
if(mysql_num_rows($SQL ) > 0){
$i=0;
while($SQL_RESULT = mysql_fetch_object($SQL)){
$responce->data[$i]['reciept_no'] = $SQL_RESULT->reciept_no;
$responce->data[$i]['time'] = $SQL_RESULT->date;
$responce->data[$i]['user'] = $SQL_RESULT->user;
$i++;
}
}
$SQL = mysql_query("SELECT * FROM `receipts2` WHERE DATE(date) = '2011-08-03'");
if(mysql_num_rows($SQL ) > 0){
$i=0;
$responce->success = true;
while($SQL_RESULT = mysql_fetch_object($SQL)){
$responce->data[$i]['reciept_no'] = $SQL_RESULT->reciept_no;
$responce->data[$i]['time'] = $SQL_RESULT->date;
$responce->data[$i]['user'] = $SQL_RESULT->user;
$i++;
}
}
else{
$responce->success = false;
$responce->data = '';
$responce->reason = "No Activity...";
}
echo json_encode($responce);
Is that your question?