Retrieve database information and check results for certain conditions - php

I am looking for the most efficient method to do the following...
I have a table with three fields: id, eventid and movetype - and I have the following code to query the database for all entries with a matching eventid :
$get_results = mysql_query("SELECT * FROM table WHERE eventid='$eventid'");
while($row = mysql_fetch_array($get_results)){
// store results in array
$move_type_array = explode(" ", $row['movetype']);
}
Please note: movetype can only be three values: Internal, Outgoing, Incoming
Using a set of dummy data, var_dump($move_type_array) could output:
array(1) { [0]=> string(8) "Internal" } array(1) { [0]=> string(8) "Internal" }
Another example of an output would be:
array(1) { [0]=> string(8) "Internal" } array(1) { [0]=> string(8) "Incoming" } array(1) { [0]=> string(8) "Outgoing" }
I then need to check the output to see if the following conditions are met:
Does the array contain Internal twice?
If the array only contains Internal once, then does the array also contain Incoming and Outgoing?
If either of the conditions are met then a message should be displayed telling them which condition has been met, otherwise a message should tell them that the conditions have not been met.
I have tried using a number of PHP functions such as in_array(), and also tried storing the data in a string and using preg_match() however I was unsuccessful in both methods.

Try this:
$result = mysql_query("
SELECT SUM(IF(movetype = 'Internal', 1, 0)) AS internal,
SUM(IF(movetype = 'Outgoing', 1, 0)) AS outgoing,
SUM(IF(movetype = 'Incoming', 1, 0)) AS incoming
FROM table
WHERE eventid = $eventid
GROUP BY eventid
");
$count = mysql_fetch_array($result);
if ($count['internal'] >= 2 || ($count['internal'] == 1
&& $count['outgoing'] >= 1
&& $count['incoming'] >= 1)) {
echo 'Yes';
} else {
echo 'No';
}

// 1. Don't use '*' - fetch only required fields!
// 2. Don't use mysql_* functions - they are obsolete! Use PDO or MySQLi instead.
$get_results = mysql_query("SELECT `movetype` FROM table WHERE eventid='$eventid'");
while($row = mysql_fetch_array($get_results)){
// Count the values
$arr = array_count_values(explode(" ", $row['movetype']));
// Check them here
if(isset($arr['Internal'])) {
if($arr['Internal'] === 2)
echo ' Internal: 2'.PHP_EOL;
else if($arr['Internal'] === 1
&& isset($arr['Incoming'])
&& isset($arr['Outgoing']))
echo ' Internal: 1, Incoming and Outgoing'.PHP_EOL;
}
}

Related

Check if array contains a duplicate value in string with PHP

I want to check if my array contains a duplicate value. I have a form where i pass a Chapter ID with the following method:
<input name="chapter_id[]" type="number" value="<?= $row_chapter_list['chapter_id'] ?>">
To update my database i pick this input and do the update w/o any issues:
if (isset($_POST['chapter_id'])) {
// Update Kapitelnummer
$statement = $pdo->prepare("UPDATE questionaire_chapter SET chapter_id = :chapter_id WHERE id = :id");
$statement->bindParam(":chapter_id", $chapter_id, PDO::PARAM_STR);
$statement->bindParam(":id", $id, PDO::PARAM_INT);
foreach ($_POST['chapter_id'] as $index => $chapter_id) {
$id = $_POST['chapter_inc_id'][$index];
$statement->execute();
}
}
A typical var_dump result looks like:
array(3) { [0]=> string(1) "1" [1]=> string(2) "12" [2]=> string(2) "12" }
In this array example the value "12" is present in two strings. I would like to create a mechanic to count double values and and use the result in a PHP if/else. i want to avoid that the a duplicate chapter ID gets written into my database.
My first try to count the string is this:
print_r(array_count_values($_POST['chapter_id']));
Which gives me a result like this
Array ( [1] => 1 [12] => 2 )
Now i am missing the method to implement a if else to check if the result is not 1.
Any idea how to do this?
You can use array_unique() to get an array where any duplicates has been filtered out. Using that, you can compare it to the original array:
if ($array != array_unique($array)) {
echo "The arrays are not the same, which means that there are duplicates";
}

How to compare array values to check correct answer

I am working on a quiz app, so the users have MCQ's and on submitting the quiz I need to show the result.
Here is the answers table in the mysql db. Similarly, There is questions table which has the id and question columns, containing the question id and question respectively.
So I am querying the db from the model like this, this returns me an associative array:
$testQuery = $this->db->query("SELECT quiz_id, correct_option FROM answers");
if ($testQuery->num_rows() > 0) {
return $testQuery->result_array();
}
Here, I'm printing the array in my controller, Which looks like this on doing the foreach:
$allCorrectOptions = $this->DataModel->readCorrectOptions();
$asize = sizeof($allCorrectOptions);
for($i = 0; $i < $asize; $i++){
echo "<pre>";
var_dump($allCorrectOptions[$i]);
echo "</pre>";
}
The Result of the above snippet:
array(2) {
["quiz_id"]=>
string(2) "13"
["correct_option"]=>
string(13) "Maruti suzuki"
}
array(2) {
["quiz_id"]=>
string(2) "14"
["correct_option"]=>
string(6) "Kotlin"
}
array(2) {
["quiz_id"]=>
string(2) "15"
["correct_option"]=>
string(4) "BOSS"
}
In the view there are radio input tags and the name attribute contains an array (allques) with quiz_id as key so when the user submits the test, I'm doing this to get the quiz_ids and selected values.
$nums = $this->input->post('allques');
foreach ($nums as $key => $value) {
echo "<br>" . $key . "==" . $value;
}
The Result of the above snippet:
13==Maruti suzuki
14==MongoDB
15==Ubuntu Linux
So what I am thinking of doing is, getting the array result of the db query similar to the the snippet result above, so that I can compare the quiz_id and correct_option's with the user submitted values with the help of a loop like: if quiz_id.this == submitted quiz_id && correct_option.this == submitted value then correct_answers++. After that showing the result
If this approach of checking is not effective, then is there any other way to do this properly.
I have figured it out, it can be done like this.
foreach ($allCorrectOptions as $key) {
echo $key['quiz_id'] . "==" . $key['correct_option'] . "<br>";
}

How to convert a database row into a JSON string of values only in PHP?

I am trying to provide a count of certain sizes of lockers. My SQL statement is:
$sql = "SELECT Concat(`Height`, 'x', `Width`, 'x', `Depth`) as Locker, count(*) from lockers GROUP BY `Height`, `Width`, `Depth` ";
a var_dump in a loop of the rows gives me the following (many more rows are possible):
array(2) { ["Locker"]=> string(8) "15x30x45" ["count(*)"]=> int(6) }
array(2) { ["Locker"]=> string(8) "45x30x45" ["count(*)"]=> int(4) }
I want to obtain a JSON string that looks like this:
{
"SizeList": {
"15x30x45": 6
"45x30x45": 4
}
}
I have tried a lot of different methods (including converting it into an object, but I can't get the value of the size as an index. For example, I get different variations of:
[0]=> string(31) "{"Locker":"15x30x45","count(*)":6}"
[1]=> string(31) "{"Locker":"45x30x45","count(*)":4}"
Any help appreciated...
You could just manually create the object like this:
$sizeList = new stdClass();
foreach ($results as $row) {
$sizeList->{$row['Locker']} = $row['count(*)'];
}
echo json_encode(array('SizeList' => $sizeList));

in php Foreach loop moves to the wrong key

I have the following array structure
jobs = {70811 ={....invoices = { A="A",...},...},...}
Then I have two nested loops. The outer nested loop seeks each job # in this case 70811. The inner loop then seeks each invoice listed for the job.
in each loop I query one of the tables
foreach ($this->p['jobs'] as $job => $value) {
$sql = 'select concat(sum(i.`AMOUNT`))as `amount`, ...
from `invoice` i
where i.`JOBID` = '.$job.'
group by i.`tracknum` = "'.$this->cTrackKey.'"';
$cmeJobEdits = 0;
if ($result = $db->query($sql))
{
if ($result->num_rows > 0)
{
$this->budget = mysqli_fetch_all( $result, $resulttype = MYSQLI_ASSOC );
$subTot = 0;
for ($i=0; $i<count($this->budget);$i++)
{
$subTot += $this->budget[$i]['amount'];
}
...
unset($i);
$xsql = 'update `cmejob` set `balance` = '.$this->budget[0]['balance'].',... where `jobid` = '.$job;
if (!$result = $db->query($xsql))
{
throw new Exception("Query to update budget failed!");
}else{
$cmeJobEdits++;
}
unset($xsql);
}
}else{
throw new Exception("Query to get billed amounts for this job failed! "`enter code here`);
}
unset($sql);
unset($value);
}//end loop updating cme jobs
My problem is this the outer query where the $job variable is not the next job # but the nested array key "invoices" as shown below.
As shown in the code I tried unsetting the query and key variables in the loops with no success.
select concat(sum(i.`AMOUNT`))as `amount`, ...
from `invoice` i
where i.`JOBID` = invoices //this is the value of the variable $job
group by i.`tracknum` = "'.$this->cTrackKey.'"';
Here is the var_dump($this->p['jobs'] of the values as you requested. Is this how you prefer seeing it
array(1) { [84528]=> array(6) { ["thisBudget"]=> string(4) "0.00" ["thisBilled"]=> string(9) "44,633.80" ["thisSum"]=> string(9) "28,003.00" ["thisBalance"]=> string(10) "-72,636.80" ["invoices"]=> array(1) { ["A"]=> string(1) "A" } ["DORMANT"]=> string(0) "" } }
The problem has been resolved.
As usual the error occurred in code not shown. The code above added an 'invoices' element to the $this->p['jobs'] array when it should have been added somewhere else.
now the loop works as described.

How can I extract data in an ordered way from a php array?

I'm not a php ninja, so please bear with me on my query. I have the following code (in simplified example format here as a lot of other irrelevant stuff is happening in the real code):
Database connection already successfully defined and handled by an include at the start of the php file.
// Define our $now value to compare times with
$now = time();
// Define the numerical timestamps required for calculating stuff
$min1st = 5140800; //59.5 days
$max1st = 5227200; //60.5 days
$min2nd = 7732800; //89.5 days
$max2nd = 7819200; //90.5 days
$delmar = 10368000; //120 days
// Get each relevant entry from the key table
try {
$stmt = $conn->prepare("SELECT * FROM keyTable WHERE `status` = 'neutral' ORDER BY `lastModified` ASC");
$stmt->execute();
$result = $stmt->fetchAll();
} catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
// Set up some instance counters
$a = 0;
$b = 0;
$c = 0;
// Create some arrays to pop the data into from the next stage so we can use it again later
$arrA = array();
$arrB = array();
$arrC = array();
So far so good. The next part is designed to discover which of the database results have a "lastModified" value set within a specified timeframe, using some data we set up near the top. This works too, fairly well (I think).
foreach($result as $value) {
// Lets find the ones that qualify for first email notification
if((($value['lastModified'] + $min1st) < $now) && (($value['lastModified'] + $max1st) > $now)) {
// Now only the entries that have been untouched for 60 days from today are listed here. Yay! Send out an email to the people responsible and remind them! Get user data...
try {
$stmt = $conn->prepare("SELECT * FROM users WHERE `uID` = :uid");
$stmt->bindValue(':uid', $value['uID']);
$stmt->execute();
$uRes = $stmt->fetchAll();
} catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
// Add +1 to the incremental count
$a++;
// Collect some data for the log email
$arrA[] = $value['entryKey']."-"$value['entryID'];
$arrA[] = $value['entryName'];
$arrA[] = $value['entryTitle'];
$arrA[] = $value['dateStarted'];
$arrA[] = $value['lastModified'];
$arrA[] = $uRes[0]['title']." ".$uRes[0]['firstName']." ".$uRes[0]['lastName'];
$arrA[] = $uRes[0]['email'];
Then it will on to send each person that gets turned up in this if. The code for sending the emails out etc works perfectly, so no need to bore you all with that. The same process is repeated each time with other parameters - you can likely guess how that works by observing the other numerical timestamp values near the top. So lets go to the end of this (which is where the question lies, after the:
}
}
And now here I want to pull all the data out of $arrA (and also the respective other arrays $arrB and $arrC) so I can pop that all into a tidy table then mail it off to admin so they know what exactly happened when this was all run.
My issue is, I do not know how to extract in a usable way, $arrA. If I var_dump($arrA); I successfully get all the stuff that should be in there but I don't see a way to order it in a nice row by row method per loop performed. I tend to end up with this when performing a var_dump($arrA);:
array(14) { [0]=> string(15) "ABC-63" [1]=> string(36) "Fish and Chips" [2]=> string(33) "Cod Disposal" [3]=> string(22) "1447283057" [4]=> string(22) "1447286317" [5]=> string(21) "Mr Bob Smith" [6]=> string(22) "bob.smith#mail.com" [7]=> string(15) "XYZ-104" [8]=> string(23) "Blue Socks" [9]=> NULL [10]=> string(22) "1447286691" [11]=> string(22) "1447326523" [12]=> string(20) "Mrs Rosie Jones" [13]=> string(34) "r.jones#mail.com" }
Clearly there is output here for two data entries. I'd to know how to shape this into an output that would basically look like this:
<tr>
<td>ABC-63</td>
<td>Fish and Chips</td>
<td>Cod Disposal</td>
<td>1447283057</td>
<td>1447286317</td>
<td>Mr Bob Smith</td>
<td>bob.smith#mail.com</td>
</tr>
<tr>
<td>XYZ-104</td>
<td>Blue Socks</td>
<td>NULL</td>
<td>1447286691</td>
<td>1447326523</td>
<td>Mrs Rosie Jones</td>
<td>r.jones#mail.com</td>
</tr>
Table start and end would obviously be in place before and after the loop respectively.
How can I achieve this result from $arrA? Do I need to modify the way I am storing this data in array's earlier on, in some manner, in order to have some sort of easy way to manage this output near the end?
Thanks in advance.
If I understand correctly, you want to output elements of $arrA, 7 elements per line.
What you can do is iterate over $arrA, filling up a temporary array $line with the elements of $arrA. Every 7 elements, the line will be filled up. You can then do anything with it like echoing it to standard output our adding it to an email variable, and then reset the $line.
$line = [];
for ($i = 0; $i < count($arrA); $i++) {
$line[] = $arrA[$i];
if ($i % 7 == 6) { //line is filled up with 7 elements
echo implode($line, " | "); //output elements of line separated with pipe char
$email .= implode($line, " | ") . "\n"; //add the line to email body
$line = []; //reset line
}
}
This one's gonna help:
foreach($arrA as $index=>$value){
echo($value.' |');
}
Styling is up to you. But if you need further help, keep me updated.
Thanks to #quentinadam I was inspired to try this. It's not the angle I was thinking of using but it does work.
echo "<table border=\"1\">\n<tbody><tr>\n";
$i = 0;
foreach($arrA as $thing) {
if($i == 7) {
echo "</tr>\n<tr>\n";
}
echo "<td>".$thing."</td>\n";
$i++;
if($i == 8) {
$i = 1;
} else {
$i = $i;
}
}
echo "</tr></tbody>\n</table>\n\n";
I'd up-vote quentinadam for being on the right track but cannot yet up-vote.

Categories