I'm trying to fetch all rows to an array variable
array that i want is like this
$data1 = array('fields'=>array(
array(
'id' => 1,
'nama_file' => "sunset.jpg",
'judul' => "Sunset",
'isi' => "Matahari terbenam indah sekali",
),
array(
'id' => 2,
'nama_file' => "water_lilies.jpg",
'judul' => "Bunga Lilly",
'isi' => "Bunga lilly air sangat indah",
),)
And I've done this:
$q = $this->db->query('select id, nama_file, judul, isi from tfoto where dihapus ="T" ');
$data1=array('fields');
foreach($q->result() as $row) {
$data1['fields']=array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
}
test output:
<?php
foreach($fields as $field){
echo $field['nama_file'];
.
.
.
};?>
and I got Message: Illegal string offset 'nama_file';'judul'; etc.
I am a newbie to MySQL/PHP, so forgive me if this is a very basic question. I tried looking all over but I could not find an answer to it.
This line:
$data1['fields']=array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
Should be:
$data1['fields'][] = array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
Because you have to append new arrays to $data1 and not replacing it.
Related
I am new with coding and I just can't seem to get my head around this. A little help or tip is much appreciated.
Basically I want an array with Questionnaires, which consist of id, name and a sub array of questions. Questions also consist of id and name.(1 Questionnaire can have multiple questions)
Something like this is what I am looking for:
[{Questionnaires{id:x, name:x, questions:{id:x, name:x},{id:x2, name:x2}}]
This is my query
SELECT questionnaires.id QuestionnaireId, questionnaires.title QuestionnaireTitle, questions.id QuestionId, questions.text Question
FROM questionnaires INNER JOIN questionnaireshasquestions qa ON qa.idQuestionnaire = questionnaires.id
INNER JOIN questions ON questions.id = qa.idQuestion
And my PHP Code:
while ($row = $conn->fetch()) {
if (!isset($data['questionnaires'][$row['QuestionnaireId']])) {
$data['questionnaires'][] = array(
'id' => $row['QuestionnaireId'],
'title' => $row['QuestionnaireTitle'],
'questions' => array(
'id' => $row['QuestionId'],
'text' => $row['Question']
)
);
} else {
$data['questionnaires'][$row['QuestionnaireId']][] = array(
'questions' => array(
'id' => $row['QuestionId'],
'text' => $row['Question']
)
);
}
The JSON array I get with this is in a wrong/incorrect format:
{"questionnaires":[{"id":"1","title":"Are you hungry?","questions":{"id":"1","text":"How is your passion? "}},{"id":"1","title":"Are you hungry?","questions":{"id":"2","text":"Do you drink?"}},{"id":"2","title":"How are you feeling?","questions":{"id":"1","text":"How is your passion? "},"0":{"questions":{"id":"3","text":"Do you like fish?"}}},{"id":"5","title":"Is testing working?","questions":{"id":"4","text":"How is the testing?"}}]
As you can see, it repeats the same Questionnaire for each Question within...
I hope I explained well what I am trying to do here :)
Your collection method was a bit "broken".
This should work:
while ($row = $conn->fetch()) {
$id = $row['QuestionnaireId'];
if (!isset($data['questionnaires'][$id])) {
// First time we get this "QuestionnaireId" -
// define "container" that collects the related questions.
$data['questionnaires'][$id] = [
'id' => $row['QuestionnaireId'],
'title' => $row['QuestionnaireTitle'],
'questions' => [],
];
} else {
// Already got this "container" -
// put the question into the collection.
$data['questionnaires'][$id]['questions'][] = [
'id' => $row['QuestionId'],
'text' => $row['Question']
];
}
}
I have a simple joined table that looks like this.
NO CLASS NAME STATUS
1 1A JOHN 1
2 1A SARA 1
3 1A LYOD 1
4 1B JOHN 1
5 1B SHIN 1
I use textbox to display the CLASS and a TEXTAREA to display the NAME. The output of CLASS 1A should like this:
Class : 1A
Name : JOHN, SARA, LYOD
How to do it using the joined table only (not multiple query)?
THis is how I loop the result:
$query = $this->xxx->yyy($class_name); //JOINED RESULT
$data = array(
'titlepage' => APP_TITLEPAGE,
'record' => $query, //This is the result that is sent to the view
'complete' => 'true',
'loadmethod' => 'add',
'contentpage' => 'test_page/detail'
);
$this->load->view('shared/master_app', $data);
so your query array is something like this:
$query = [
['NO' => 1, 'CLASS' => '1A', 'NAME' => 'JOHN', 'STATUS' => '1'],
['NO' => 2, 'CLASS' => '1A', 'NAME' => 'SARA', 'STATUS' => '1'],
['NO' => 3, 'CLASS' => '1A', 'NAME' => 'LYOD', 'STATUS' => '1'],
['NO' => 4, 'CLASS' => '1B', 'NAME' => 'JOHN', 'STATUS' => '1'],
];
You may make a function that arrange it or group it
lets name it groupResults($query)
function groupResults($query) {
$result = [];
foreach($query as $queryItem) {
$result[$queryItem['CLASS']][] = $queryItem['NAME'];
}
return $result;
}
now result is looks like this:
$result = [
'1A' => ['JOHN', 'SARA', 'LYOD'],
'1B' => ['JOHN']
]
this is a snapshot of what I got:
so now you can use it like this
$query = $this->xxx->yyy($class_name); //JOINED RESULT
$data = array(
'titlepage' => APP_TITLEPAGE,
'record' => groupResults($query), //This is the result that is sent to the view
'complete' => 'true',
'loadmethod' => 'add',
'contentpage' => 'test_page/detail'
);
$this->load->view('shared/master_app', $data);
now in the view you may loop on this array as:
foreach($record as $class => $names) {
echo "<input type='text' value='" . $class . "'>";
echo "<textarea>" . implode(', ', $names) . "</textarea>";
}
If you want to add all name in same Class in one column then it can be possible by GROUP_CONCAT() mysql function.
adjust your query with GROUP_CONCAT. For an example see below
SELECT CLASS, GROUP_CONCAT(NAME)
FROM table_name
GROUP BY CLASS;
It will Output like this
1A JOHN,SARA,LYOD
2A JOHN,SHIN
You also can put custom separator between names using GROUP_COCAT separator
SELECT CLASS, GROUP_CONCAT(NAME SEPARATOR ' -- ')
FROM table_name
GROUP BY CLASS;
For reference MySql GROUP_CONCAT()
I am working on a project and I am stuck on this my question is I have one array which is like below
$arr1 = array(
array
(
'id' => '1',
'city' => 'A.bad',
),
array
(
'id' => '2',
'city' => 'Pune',
),
array
(
'id' => '1',
'city' => 'Mumbai',
)
);
and I have to compare the this by id and I want the output like below.
$result = array(
array(
'id'='1',
'city'='A.bad','Mumbai'
),
array(
'id'='2',
'city'='Pune'
)
);
if we have same id as in the first one is A.bad so it will take it and in the third one it has id 1 and city as mumbai so it will combine as id 1 and city as a.bad,mumbai and other records are filtered in same manner.
Loop through the array and generate a new array depending on the id.You can try this -
$new = array();
foreach($arr1 as $array) {
$new[$array['id']]['id']= $array['id'];
// check if the city value set for that id
// if set the concatenate else set with the city name
$new[$array['id']]['city']= (isset( $new[$array['id']]['city'])) ? ($new[$array['id']]['city'] . ',' . $array['city']) : $array['city'];
}
Fiddle
If you are getting that data from database the you can group them in the query also.
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 6 months ago.
Hah, I had no idea how else to phrase that. I'm trying to reformat a set of three arrays generated by form field inputs, into something that better matches my models, so I can save the values to the db.
Not sure if the solution should be some array manipulation or that I should change the "name" attribute in my form fields.
currently I have an array of my input data:
array(
'image_id' =>
array
0 => '454' (length=3),
1 => '455' (length=3),
2 => '456' (length=3)
'title' =>
array
0 => 'title1' (length=6),
1 => 'title2' (length=0),
2 => '' (length=6)
'caption' =>
array
0 => 'caption1' (length=8),
1 => '' (length=8),
2 => 'caption3' (length=8)
);
and would like to change it to something like, so I can iterate over and save each array of values to the corresponding resource in my db.
array(
0 =>
array
'image_id' => '454',
'title' => 'title1',
'caption' => 'caption1'
1 =>
array
'image_id' => '455',
'title' => 'title2',
'caption' => ''
2 =>
array
'image_id' => '456',
'title' => '',
'caption' => 'caption3'
);
This would iterate through the array with 2 foreach loops. They would use each other's key to construct the new array, so it would work in any case:
$data = array(
'image_id' => array(454, 455, 456),
'title' => array('title1', 'title2', ''),
'caption' => array('caption1', '', 'caption3')
);
$result = array();
foreach($data as $key => $value) {
foreach ($value as $k => $v) {
$result[$k][$key] = $v;
}
}
This'll do it:
$array = call_user_func_array('array_map', array_merge(
[function () use ($array) { return array_combine(array_keys($array), func_get_args()); }],
$array
));
Assuming though that this data is originally coming from an HTML form, you can fix the data right there already:
<input name="data[0][image_id]">
<input name="data[0][title]">
<input name="data[0][caption]">
<input name="data[1][image_id]">
<input name="data[1][title]">
<input name="data[1][caption]">
Then it will get to your server in the correct format already.
I have three database tables, question_set, question and answer.
question_set contains set_name and set_id
question contains question and also question_set_id
answer contains answer , question_id
I can not work out a way to show all the data in one view file,
I tried joins but then question data is repeating with it prints because every question has three or four answer.
Just thought I would point out.
Your database design is horrible.
It will not scale well, and infact I do not think it would actually. work.
The way I would do it is
Three tables
sets => id, name
questions => id, set_id, question
answers => id, set_id, question_id, answer, points
Note that in my above example I am taking it one step further, rather than each answer being true or false, it can have an assigned point value.
hence, an answer that you deemed half correct could be given 5 points, where as a correct answer could be given 10 points, it also works as a boolean true, just have a correct answer as 1 point, and an incorrect answer as 0 points
Anyway.
With the above table design in mind.
You could do
$this->db->select('s.id as set, s.name as name, q.id as qid, q.question as qu, a.id as aid, a.answer as an, a.points as p')
->from('sets s')
->join('questions q', 'q.set_id = s.id')
->join('answers a', 's.set_id = s.id')
->where('s.id', 'SET ID');
$questions = $this->db->get();
$set = array('questions' => array());
foreach($questions as $s){
$set['id'] = $s->set;
$set['name'] = $s->name;
$set['questions'][$s->qid]['id'] = $q->qid;
$set['questions'][$s->qid]['question'] = $q->qu;
if(!isset($set['questions'][$s->qid]['answers']))
$set['questions'][$s->qid]['answers'] = array();
$set['questions'][$s->qid]['answers'][] = array(
'id' => $q->aid,
'answer' => $q->an',
'points' => $q->p
);
}
So then you end up with an array that looks something like
array(
'id' => 1,
'name' => 'My first quiz',
'questions' = array(
array(
'id' => 1,
'question' => 'What is 1+1+1?',
'answers' => array(
array(
'id' => 1,
'answer' => 1,
'points' => 0
),
array(
'id' => 2,
'answer' => 2,
'points' => 0
),
array(
'id' => 3,
'answer' => 3,
'points' => 1
)
)
),
array(
'id' => 2,
'question' => 'What is 2+2+2?',
'answers' => array(
array(
'id' => 4,
'answer' => 6,
'points' => 1
),
array(
'id' => 5,
'answer' => 2,
'points' => 0
),
array(
'id' => 6,
'answer' => 3,
'points' => 0
)
)
)
)
);
Then you can do.
echo '<h2>'.$set['name'].'</h2>';
foreach($set['questions'] as $q){
echo '<div class="question">';
echo '<h3>'.$q['question'].'</h3>';
echo '<div class="answers">';
foreach($q['answers'] as $a){
echo '<label for="a'.$a['id'].'">'.$a['answer'].'<input type="checkbox value="'.$a['id'].'" name="q'.$q['id'].'" /></label><br />';
}
echo '</div>';
echo '</div>';
}
The easiest way, but which of course requires more SQL calls, is to use nested loops for this.
1) Join the question set and question tables
2) For each entry in the result set, retrieve the answers for that entry and put it in a separate array, nested in a bigger array where the key is the id of the question.
Your view would then look something like this:
foreach($questions as $question)
{
//Print question information
$answers = $answers_array[$question['id']];
foreach($answers as $answer)
{
//Print answers information
}
}
Might not be best practice but it will do the trick.