How generate column using for loop - php

How to make this function produce column occLvl_ loop 3 time and using explode to fetch each value from sql CONCAT. So the result will become like this.
[{
"accommodationID": "LA56",
"occLvl_0": "40.00",
"occLvl_1": "70.00",
"occLvl_2": "90.00"
}]
function getOccLevel(){
global $ehorsObj;
$occArray = array();
$sql = "SELECT accommodationID, GROUP_CONCAT(occLevelDesc) AS occLevels
FROM tblSamAccOccLevels
WHERE ACTIVE = 'y'
GROUP BY accommodationID
ORDER BY accommodationID ASC, occLevelDesc ASC ";
$GetResult = $ehorsObj->FetchData($sql, $ehorsObj->DEFAULT_PDO_CONNECTIONS);
while ($row = $GetResult->fetch()){
$occArray[] = array(
'accommodationID' => $row['accommodationID'],
);
//seem the method below is not working
for ($j = 0; $j < 3; $j++) {
$occArray["occLvl_".$j] = explode(",", $row['occLevels'])
}
}
header("Content-type: application/json");
$result = json_encode($occArray);
echo $result;
}
Result of the query
accommodationID occLevels
LA56 40.00, 70.00, 90.00

Making numerically named object properties/variables (occLvl_0 etc.) is generally a bad idea as it makes it difficult to work with them in any regular manner (e.g. using a loop). It is better practice to put the values into an array:
while ($row = $GetResult->fetch()){
$occArray[] = array(
'accommodationID' => $row['accommodationID'],
'occLvl' => explode(",", $row['occLevels'])
);
}
This will give you an output JSON that looks something like:
[
{
"accommodationID": "LA56",
"occLvl": [
40,
70,
90
]
},
{
"accommodationID": "PQ45",
"occLvl": [
30,
60,
100
]
},
...
]
And in your JS you can then iterate over the occLvl array to get the values.
If you need the data in the form you describe, then you need to iterate over the exploded occLevels value to generate the individual values, pushing them with the accommodationID into a new array and then pushing that array to $occArray:
while ($row = $GetResult->fetch()){
$this_occ = array(
'accommodationID' => $row['accommodationID'],
);
foreach (explode(",", $row['occLevels']) as $key => $occLvl) {
$this_occ["occLvl_$key"] = $occLvl;
}
$occArray[] = $this_occ;
}

Explode returns an array. You should explode before the loop and iterate through the result of that explode in the loop

Related

Getting a an array from for loop and use another for loop with that array in PHP

I have a for loop, and will form two arrays in the loo
foreach ($data as $key => $value) {
........
........
$user_insert[] = [
'keyy' => $value,
'key' => $value,
....
...
...
];
$someArray1[] = [
/*'user_id' => $insert_id,*/
'key1' => $value1,
'keyy' => $value,
.......
........
];
}
the count of $user_insert[] array is 4, the count of $someArray1 is 15.
after this for loop, I need to insert $user_insert array data to the database and use that inserted_id to insert next array $someArray1
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
foreach ($someArray1 as $someArray) {
$someArray['user_id'] = $insert_id;
DB::table('table_name')->insert($someArray);
}
}
So the problem here is the data in the second loop is inserting 60 times(4 * 15). I need to insert only 15 rows.
The data($someArray1) is coming from the first for loop, but I need to add a user_id to that array which I get after the insert operation in second for loop.
So how can i insert only 15 rows.
I'm going to assume that you are able to access your $someArray1 using the $insert_id value to find the appropriate user data.
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Get the user information you need as $someArray1 should be user_id=>data
$userData = $someArray[$insert_id];
$userData['user_id'] = $insert_id;
// No need for an inner loop, just access the necessary properties of the loop you created earlier.
DB::table('table_name')->insert($userData);
}
Your tags indicate that you are using Laravel 5 too. If you are using the eloquent ORM, some of the insertion and ID retrieval can be cleaned up by creating Models for your DB tables.
Actually, each time you process a line from $user_insert, you loop over $someArray1 instead of fetching just the line you need.
The thing is to understand the line you need. As much as I can understand your piece of code, I would say the easiest (most readable) way of doing it is by using a for loop, not a foreach one :
for( $i = 0, $iMax = count( $user_insert ); $i < $iMax; ++$i ){
$insert_user = $user_insert[$i];
// Put your `$user_insert` insert code here
$someArray1[$i]['user_id'] = $insert_id;
DB::table('table_name')->insert( $someArray[$i] ); // Note the [$i] here
}
You also may do that with foreach by requesting indices :
foreach( $user_insert as $i => $insert_user ){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Now use $i requested above :
$someArray1[$i]['user_id'] = $insert_id;
DB::table( 'table_name' )->insert( $someArray1[$i] );
}

Multi-dimensional array to JSON

I am trying to print my data and encode it into JSON. I'm extracting the data from my MySQL database for a quiz. The data that I am trying to extract 1 question, 1 category and 4 options to make a set of quiz. I think I nearly got it how to make it work but I failed to find out how. This was the result check in this link.
Paste the JSON to this link so that you can easily format it. From that JSON data, I want to output like this for each question:
"What is the approximate number of islands that comprise the Philippines?",
"Philippine Geography",
[
{
"quiz_choice_id":"5",
"choice":"7000",
"is_correct_choice":"1"
},
{
"quiz_choice_id":"6",
"choice":"6000",
"is_correct_choice":"0"
},
{
"quiz_choice_id":"7",
"choice":"8000",
"is_correct_choice":"0"
},
{
"quiz_choice_id":"8",
"choice":"9000",
"is_correct_choice":"0"
}
],
This is my code for that:
<?php
/**
* Created by PhpStorm.
* User: Muhammad
* Date: 19/04/2016
* Time: 00:46
*/
require_once('Database_Connect.php');
$questions_query = "SELECT question, quiz_choice_id, choice ,is_correct_choice, category FROM category_question cq, question q, question_choices qc WHERE q.quiz_question_id = qc.quiz_question_id AND q.cat_ques_id = cq.cat_ques_id LIMIT 10";
$questions_query_result = mysqli_query($con, $questions_query) or die("error loading questions");
$questions_results = array();
encode_result($questions_query_result);
function encode_result($result)
{
//$response = array();
$questions = array();
//$choices = array();
while ($r = mysqli_fetch_array($result)) {
//$response[] = $r;
//$questions = array('question' => $r[0]);
$questions[] = $r['question'];
$questions[] = $r[4];
$choices[] = array('quiz_choice_id' => $r[1], 'choice' => $r[2], 'is_correct_choice' => $r[3]);
$questions[] = $choices;
//array_push($questions, $questions['question']);
//array_push($questions_results, $questions);
}
echo json_encode(array('questions'=>$questions));
}
mysqli_close($con);
The design of the database is this:
I can't find a way to make it work because from the database quiz_choice_id,choice, is_correct_choice are in a different table but I combined all into one table as you can see in my SQL statement $questions_query. Please let me know how can I fix this. Thanks in advance.
Do you want the json to look like this?
[ {
"question" : "What is the approximate number of islands that comprise the Philippines?",
"category" : "Philippine Geography",
"choices" : [
{
"quiz_choice_id":"5",
"choice":"7000",
"is_correct_choice":"1"
},
{
"quiz_choice_id":"6",
"choice":"6000",
"is_correct_choice":"0"
},
{
"quiz_choice_id":"7",
"choice":"8000",
"is_correct_choice":"0"
},
{
"quiz_choice_id":"8",
"choice":"9000",
"is_correct_choice":"0"
}
]
},{
..... // next question
}]
You'll have to do something like this, but I have no idea what the results of the query is.
$questions = array();
while ($r = mysqli_fetch_array($result)) {
$key = $r['quiz_question_id']; // you need a key here that is unique to the question, so i think this will do looking at the schema you posted, this will group them in that segment of the array.
if( !isset( $questions[$key] ) ){
//if we never had this question, create the top level in the results
$questions[$key] = array(
'question' => $r['question'],
'category' => $r['category'],
'choices' => array()
);
}
//add in the choices for this question
//on the next iteration, the key is the same so we only do this part
//and append that rows choices to the previous data using $key to match the question
$questions[$key]['choices'][] = array('quiz_choice_id' => $r['quiz_choice_id'], 'choice' => $r['choice'], 'is_correct_choice' => $r['is_correct_choice']);
}
Make sure to add quiz_question_id to your query if this is the questions id, unique identifier. Essentially this will group them together, as this will be the same for each row with that question's choices.
I added string keys to the output, I wouldn't mix using string keys and numbered index. I hope I mapped them out right.
Also I haven't tested this at all, so sorry if there are any syntax errors.

Summing the values of two arrays in php

There is a problem:
After submitting a form I receive the indexed array as a SQL-query result and the goal is to sum each next array values with the values of previously received arrays and put the sums into result array
Example:
// 1st query result
$product_amount = [0 => 0.36,
1 => 0.14,
2 => 0.42]
// 2nd query result
$product_amount = [0 => 0.28,
1 => 0.12,
2 => 0.40]
// n-th query result
$product_amount = [0 => 0.16,
1 => 0.14,
2 => 0.42]
// the sum
$total = [0 => 0.80,
1 => 0.40,
2 => 1.24]
How to do it?
The code that creates an array:
function doseCount($num){
return ($num/100) * intval($_POST['portion']); //getting multiplier for productAmount() function
}
function productAmount(){
global $link; //connection to the MySQL server
if(isset($_POST['product'])){
$product_amount_query = 'SELECT va.vitamin_a, va.vitamin_b1, va.vitamin_b2, va.vitamin_b3, va.vitamin_b5,
va.vitamin_b6, va.vitamin_bc_b9, va.vitamin_b12, va.vitamin_c, va.vitamin_d, va.vitamin_e, va.biotin, va.vitamin_k,
va.flavonoids, va.lipoic_acid FROM products_list p, vitamins_amount va WHERE p.id = va.product_id AND p.name = ?';
$product_amount_stmt = mysqli_prepare($link, $product_amount_query);
mysqli_stmt_bind_param($product_amount_stmt, "s", $_POST['product']);
mysqli_stmt_execute($product_amount_stmt);
$result = mysqli_stmt_get_result($product_amount_stmt);
$product = mysqli_fetch_array($result, MYSQLI_NUM);
return $product_final_result = array_map('doseCount', $product);
mysqli_stmt_close($product_amount_stmt);
mysqli_close($link);
}
}
$product_amount = productAmount();
After submit $product_amount array gets new data and this new value must be summed with previous.
You could accomplish this by combining array_map and array_sum. If you're using PHP 5.6 or greater, which you should, you could write something like this:
$total = array_map(function (...$vals) {
return array_sum($vals);
}, ...$results);
Assuming that $results contains all of your $product_amount arrays.
If you want to build $total incrementally instead of passing all query results at once, you can do this:
// Initialize $total array
$total = [0, 0, 0];
// Update $total for each query
$total = array_map(function (...$vals) {
return array_sum($vals);
}, $total, $product_amount);
This problem can be solved with proper use of sessions:
if (empty($_SESSION['product_amount'])){
$_SESSION['product_amount'] = $product_amount;
}else{
foreach ($_SESSION['product_amount'] as $key => $value) {
$_SESSION['product_amount'][$key] += $product_amount[$key];
}
}
Special thanks to Mawia HL for his help.

PHP Array select result from other array

I have a sql table with some category, i get them in a array.. all fine but when i try to get data from another table foreach category, always return me for first category selected.
This is my code:
$gameguidecategoryes = array();
$gameguides = array();
$dbselectgameguidecategoryes = new DB_MSSQL;
$dbselectgameguidecategoryes->Database=$newweb_db;
$dbselectgameguidecategoryes->query("Select GameGuideCatNr,GameGuideCatName_$languageid as GameGuideCatName,GameGuideCatImage from GameGuide_Category where GameGuideCatVisible = 1 order by GameGuideCatOrder asc");
for($i=0;$i < $dbselectgameguidecategoryes->num_rows();++$i) {
if ($dbselectgameguidecategoryes->next_record()){
$GameGuideCatNr = $dbselectgameguidecategoryes->f('GameGuideCatNr');
$GameGuideCatName = $dbselectgameguidecategoryes->f('GameGuideCatName');
$GameGuideCatImage = $dbselectgameguidecategoryes->f('GameGuideCatImage');
}
$gameguidecategoryes_temp = array(
'ggcname' => $GameGuideCatName,
'ggcimg' => $GameGuideCatImage,
);
$gameguidecategoryes[$i] = $gameguidecategoryes_temp;
$dbselectgameguide = new DB_MSSQL;
$dbselectgameguide->Database=$newweb_db;
$dbselectgameguide->query("Select GameGuideID,GameGuideName_$languageid as GameGuideName from GameGuide_Content where GameGuideCat = $GameGuideCatNr and GameGuideVisible = 1 order by GameGuideOrder asc");
for($ii=0;$ii < $dbselectgameguide->num_rows();++$ii) {
if ($dbselectgameguide->next_record()){
$GameGuideID = $dbselectgameguide->f('GameGuideID');
$GameGuideName = $dbselectgameguide->f('GameGuideName');
}
$gameguides_temp = array(
'ggid' => $GameGuideID,
'ggn' => $GameGuideName,
);
$gameguides[$ii] = $gameguides_temp;
}
}
Why $gameguides return data only from first category?
Thank you
Your second loop keeps getting trashed by the first loop. e.g. Consider what happens:
You fetch your categories, and (let's pretend) there's 4 of them.
You store some information in $gameguidecategoryes[0]
You run the second query, get some content for category #0, say, 3 records
That gets stored in $gameguides[0], [1], [2]
Your outer loop ticks again, and you start on categoryes[1]
The inner loop ticks again, you get 4 records, and now you're storing them into the SAME again: $gameguides[0], [1], [2], [3], etc...
You've now trashed the data you fetched in the first loop, and will
do so for every category you fetch.
This code is very inefficient. You should learn how to use JOINs, and fetch into a single structure, e.g.
SELECT category.id, category.name, ...., content.id, content.name
FROM categories
LEFT JOIN content ON categories.id = content.category_id
ORDER BY ...
and then something like
$data = array();
while($row = fetch row from db) {
if (!isset($data[$row['category.id']]) {
$data[$row['category.id']] = array(
'name' => $row['category.name'],
'content' => array()
);
}
$data[$row['category.id']]['content'][] = array(
... save content data here
);
};
Better work on clean code
$gameguidecategoryes = $gameguides = $gameguidescategoryids = array();
$dbselectgameguidecategoryes = new DB_MSSQL;
$dbselectgameguidecategoryes->Database=$newweb_db;
$dbselectgameguidecategoryes->query("Select GameGuideCatNr,GameGuideCatName_$languageid as GameGuideCatName,GameGuideCatImage from GameGuide_Category where GameGuideCatVisible = 1 order by GameGuideCatOrder asc");
while ($dbselectgameguidecategoryes->next_record()) {
$gameguidescategoryids[] = $dbselectgameguidecategoryes->f('GameGuideCatNr');
$gameguidecategoryes[] = array(
'ggcname' => $dbselectgameguidecategoryes->f('GameGuideCatName'),
'ggcimg' => $dbselectgameguidecategoryes->f('GameGuideCatImage'),
);
}
if (count($gameguidescategoryids)) {
$dbselectgameguide = new DB_MSSQL;
$dbselectgameguide->Database=$newweb_db;
$dbselectgameguide->query("Select GameGuideID,GameGuideName_$languageid as GameGuideName from GameGuide_Content where GameGuideCat IN (".implode(',', $gameguidescategoryids).") and GameGuideVisible = 1 order by GameGuideOrder asc");
while ($dbselectgameguide->next_record()){
$gameguides[] = array(
'ggid' => $dbselectgameguide->f('GameGuideID'),
'ggn' => $dbselectgameguide->f('GameGuideName'),
);
}
}

Two MySQL result sets to a nested array

I'm having two tables of data "Item" and "Subsidiary" with the following structure:
ITEM
ItmCod
ItmName
SUBSIDIARY
ItmCodParent
ItmCodChild
I need to show a list of Items each with a list of its subsidiaries, like in this json:
{
"ItmCod":1,
"ItmName":"BogusItem1",
"Subsidiaries":
[
{
"ItmCodParent":1,
"ItmCodChild":15
},{
"ItmCodParent":1,
"ItmCodChild":16
}
]
},{
"ItmCod":2,
"ItmName":"BogusItem2",
"Subsidiaries":
[
{
"ItmCodParent":2,
"ItmCodChild":17
},{
"ItmCodParent":2,
"ItmCodChild":18
}
]
}
How can I add the second result set to the first one to have the nested as shown above. I have this code so far:
$sql = "SELECT ItmCod, ItmName FROM item";
$item_rows = array();
while($item_row = $database->fetch_array_assoc($item_result)){
$sub_sql = "SELECT ItmCodParent, ItmCodChild FROM subsidiary WHERE subsidiary.ItmCodParent = " . $item_row["ItmCod"];
$sub_result = $database->query($sub_sql);
$sub_rows = array();
while($sub_row = $database->fetch_array_assoc($sub_result)){
$sub_rows[] = $sub_row;
}
$item_rows[] = $item_row;
}
print json_encode($item_rows);
Thanks.
just above the line
$item_rows[] = $item_row;
simply add
$item_row['Subsidiaries']=$sub_rows;
I would do a single join query like this:
SELECT i.ItmCod AS ItmCod, i.ItmName AS ItmName, s.ItmCodChild AS ItmCodChild
FROM item AS i
INNER JOIN subsidiary AS s
ON i.ItmCod = s.ItmCodParent
Note I didn't select s.ItmCodParent as this is just redundant to i.ItmCod.
Then build the array like this:
$item_rows = array();
while($item_row = $database->fetch_array_assoc($item_result)){
$item_rows[(int)$item_row['ItmCod']]['ItmCod'] = $item_row['ItmCod'];
$item_rows[(int)$item_row['ItmCod']]['ItmName'] = $item_row['ItmCod'];
$sub_array = array(
'ItdCodParent' => $item_row['ItmCod'],
'ItmCodChild' => $item_row['ItmCodChild']
);
$item_rows[(int)$item_row['ItmCod']]['Subsidiaries'][] = $sub_array;
}
$item_rows = array_values($item_rows); // reset numerical indexes.
echo json_encode($item_rows);
I wouldn't attempt to solve this with two queries:
$sql = '
SELECT I.ItmCod, I.ItmName, S.ItmCodChild
FROM item I
LEFT JOIN subsidiary S ON (S.ItmCodParent = I.ItmCod)
';
// fetch $item_result with $sql
$item_rows = array();
while ($item_row = $database->fetch_array_assoc($item_result)) {
$cod = $item_row['ItmCod'];
if (!array_key_exists($cod, $item_rows)) {
$item_rows[$cod] = $item_row;
}
$item_rows[$cod]['Subsidiaries'] = array(
'ItmCodParent' => $cod,
'ItmCodChild' => $item_row['ItmCodChild'],
);
}
// array_values is because json_encode will keep the keys
// otherwise
print json_encode(array_values($item_rows));
That way, you aren't running an additional query for every single item row to get the subsidiaries (minimizing round-trip time, and letting the database do what it's good at).

Categories