I'm having trouble trying to remove null values from an array using values from the database. These null values are usually found within the 'answers'.. Code below:
$getQuestions = mysql_logging_query("SELECT fq.`question_id`, fq.`ques_form_id`, fq.`question_body`, fq.`type`, fq.`answer1`, fq.`answer2`, fq.`answer3`, fq.`answer4`, fq.`answer5`, fq.`answer6`, fq.`min_validation`, fq.`max_validation`
FROM QuestionnaireFormQuestions fq
LEFT JOIN QuestionnaireForms f
ON f.`form_id` = fq.`ques_form_id`
WHERE f.`active` = 1
AND f.`form_id` = '".mysql_real_escape_string($form_id,$this->dbcon)."'
",$this->dbcon);
if($getQuestions && mysql_num_rows($getQuestions)>0 && mysql_error($this->dbcon)=="")
{
$get_questions_array = array();
while($getQuestions && $getQuestions_rec=mysql_fetch_assoc($getQuestions))
{
$get_questions_array[] = array('question_id' => $getQuestions_rec['question_id'],
'related_form_id' => $getQuestions_rec['ques_form_id'],
'question_body' => $getQuestions_rec['question_body'],
'question_type' => $getQuestions_rec['type'],
'possible_answer1' => $getQuestions_rec['answer1'],
'possible_answer2' => $getQuestions_rec['answer2'],
'possible_answer3' => $getQuestions_rec['answer3'],
'possible_answer4' => $getQuestions_rec['answer4'],
'possible_answer5' => $getQuestions_rec['answer5'],
'possible_answer6' => $getQuestions_rec['answer6'],
'min_validation' => $getQuestions_rec['min_validation'],
'max_validation' => $getQuestions_rec['max_validation']
);
}
if(is_array($get_questions_array) && count($get_questions_array)>0)
{
foreach($get_questions_array as $key=>$array)
{
if($array === null) {
unset($get_questions_array[$key]);
}
$return['data']['questions'][] = $array;
}
}
}
else
//error
A return for example; would look like this:
"question_id":"3",
"related_form_id":"4",
"question_body":"Do you like this content?",
"question_type":"radio",
"possible_answer1":"Disagree",
"possible_answer2":"Neutral",
"possible_answer3":"Agree",
"possible_answer4":null,
"possible_answer5":null,
"possible_answer6":null,
"min_validation":"1",
"max_validation":"1"
I've tried unsetting the key using empty and isnull but to no avail. Any help would be appreciated.
You are not testing the values inside the array, you need to:
foreach($get_questions_array as $array){
foreach($array as $key=>$element){
if($element===null)
unset($array[$key]);
}
$return['data']['questions'][] = $array;
}
I think it's possible you're looping through your nested data structure at the wrong level.
You have this $get_questions_array, each element of which is an associative array that came from one row in your MySQL result set. But your php code loops over the rows of the result set, not over the columns.
I think you want something more like this, with another nested foreach.
if(is_array($get_questions_array) && count($get_questions_array)>0)
{
foreach($get_questions_array as $row)
{
foreach ($row AS $colname=>$colvalue)
{
if ($colvalue === null || $colvalue =='')
{
unset($row[$colname]);
}
}
}
}
See what's going on? Your code was throwing away whole rows that were null, but there weren't any of those, so it wasn't doing anything.
why don't you query the data that does not contain nulls, instead of removing the nulls by yourself ? let the database do this for you something like:
select * from table where possible_answer IS NOT NULL
Try this loop through the array and set them to null with the key's if the value is empty
foreach($getQuestions_rec as $key => $value){
if($value == ''){
$getQuestions_rec[$key] = null;
}
}
Use the IFNULL(ColumnName,"") to replace the null values to empty string in SQL query.
Example: IFNULL(answer6,"")
refer this this How to remove null values from an array? or you ca alter the query to select the null values from table.
Related
I have a table options and I have an array of strings ["value1", "value2", "value3"].
What I'd like to do is check if all of the values within the array are present in the table.
I've tried whereIn but I think it checks if any values exist in the table.
This is what I have done currently:
$v = ["value1", "value2", "value3"];
$options = Options::whereIn('value', $v)->get();
if ($options->count() != count($v)) {
//something must be missing
}
This works, but I wonder if there is a better way? The table has millions of records so I'd like to do only 1 query if possible.
Thanks!
The answer in the comments by justcarty is technically correct, but you can reduce the load by not pulling in the options if you don't intend to use them.
if (Option::whereIn('value', [...])->count() != count([...])) {
//perform action
}
Also note, as justcarty mentioned, this won't work if you have multiple occurrences of a value in your database, but you can get around this by adding DISTINCT clause to your query.
if (Option::distinct(['value'])->whereIn('value', [...])->count() != count([...])) {
//perform action
}
whereIn check specifically for that one value in the arrays.
You can try this:
$search_values = ['value1', 'value2', 'value3'];
$found = true;
foreach ($search_values as $search) {
if (!Search::where('column', $search)->first()) {
$found = false;
}
}
if (!$found) {
// Something must be missing
}
I need one help. I need to push single row table value into array using PHP and MySQL. I am explaining my table below.
db_tc
id tc1 tc2 tc3 tc4 tc5 tc6 tc7 tc8 tc9 tc10
1 aa bb cc dd ee ff gg hh jj
Here I need need to push all column value to single array and using same key name. I am explaining my code below.
$faqquery="select * from db_tc order by id desc limit 1";
$faqdata= $this->modl_obj->db_get_data($faqquery);
$ctr=count($faqdata);
$tcArr=array();
if($ctr >0){
foreach ($faqdata as $v) {
}
}
Here which column has blank data that will not push into array. My expected output should like below.
$tcArr=[{'tc':'aa'},{'tc':'bb'},{'tc':'cc'},{'tc':'dd'},{'tc':'ee'},{'tc':'ff'},{'tc':'gg'},{'tc':'hh'},{'tc':'jj'}]
Please help me to resolve this problem.
As #tadman said, you should consider changing the schema for the table. But as an solution for your question instead (I will only write the foreach).
foreach($faqdata as $key => $value){
if(strpos($key, "tc") !== FALSE){
$tcArr[] = [preg_replace('/\d+/u', '', $key) => $value]; //preg_replace to remove the numbers that you do not wanted in your expected output.
}
}
I haven't tested this code, and it may also varies a bit based on the MySQL output format you have, like object or array. Let me know and I will edit based on it.
EDIT:
Even though I highly recommend you to change the schema of your table!
Try this:
$faqquery="select * from db_tc order by id desc limit 1";
$faqdata= $this->modl_obj->db_get_data($faqquery);
$ctr=count($faqdata);
$tcArr=array();
if($ctr >0){
$row = $faqdata[0];
foreach ($row as $k => $v) {
if($v && $k != 'id') {
$tcArr[] = ['tc' => $v];
}
}
}
foreach ($faqdata as $key=>$value) {
if (($key!='id') && ($value!='') {
$outputarray[]="{'tc':'$value'}";
}
}
$output=implode(',',$outputarray);
$output='['.$output.']';
UPDATE:
I get array values from $_POST['changed'].
The array structure looks like this:
Array
(
[0] => Array
(
[recid] => 1
[nachname] => Müller7777
)
[1] => Array
(
[recid] => 3
[vorname] => Maria123
)
)
I get on line #3 this error: Fatal error: Function name must be a string
$uarr=array();
foreach ($_POST['changed'] as $a) {
list($x,$k)=array_keys($a);
list($y,$v)=array_values($a);
$uarr[$y][]="$k='$v'";
}
foreach ($uarr as $k=>$v) {
$sql = "";
$sql .="UPDATE tbl SET ".join(",",$v)." WHERE recid=$k";
// send UPDATE ...
}
file_put_contents('filename2.txt', $sql);
Before I do the final database UPDATE I want to check if the created array does its job. Thats why I want to write the $sql variable first into a txt-file.
------------------------------------------------
SOLUTION:
checking if $_POST['changed'] == null is the final answer for this question.
if ($_POST['changed'] == null) {
} else {
$uarr=array();
$b = $_POST['changed'];
foreach ($b as $a) {
list($x,$k)=array_keys($a);
list($y,$v)=array_values($a);
// $x contains the `recid` key
// $y ... value
$uarr[$y][]="$k='$v'";
}
foreach ($uarr as $k=>$v) {
$sql = "";
$sql .="UPDATE tbl SET ".join(",",$v)." WHERE recid=$k";
// send UPDATE ...
}
file_put_contents('filename2.txt', $sql);
}
Before you run the individual UPDATE statements - yes, for each recid value you should send one statement - you could first collect all the affected values for each recid in an associative array like
$uarr=array();
foreach ($_POST['changed'] as $a) {
list($x,$k)=array_keys($a);
list($y,$v)=array_values($a);
// $x contains the `recid` key
// $y ... value
$uarr[$y][]="$k='$v'";
}
and then do another loop like
foreach ($uarr as $k=>$v) {
$sql="UPDATE tbl SET ".join(",",$v)." WHERE recid=$k";
// send UPDATE ...
}
But, of course, this will only work correctly if the $_POST('changed') array adheres to the described format and order. And, finally, so far there is nothing in this code to protect you from SQL injection.
Try to do it like this:
$BigArray = $_POST['changed'];
$LengthOfArray = sizeof($BigArray);
for ($i = 0; $i < $LengthOfArray ; $i++) {
$SubArray = $BigArray[$i];
// Call the update/insert here
// $SubArray['recid'] is the ID
// $SubArray['vorname'] is the name
}
I would like to grab the values of several textarea fields and save them to the database. For now I have four of each with different values and I want to batch save these values, the textarea fields are:
<textarea name="compedia[]"></textarea>
<textarea name="specification[]"></textarea>
and the save function:
function saveCOA(){
$labref=$this->uri->segment(3);
$data= $this->input->post('compedia');
$data1= $this->input->post('specification');
$compedia=array(
'labref'=>$labref, //NDQA201303001
'compedia'=>$data,
'specification'=>$data1
);
foreach ($compedia as $value) {
$this->db->insert('coa_body',$value);
}
}
When I print_r($value) it returns :
NDQA201303001
Array ( [0] => Alphy [1] => poxy [2] => alphy [3] => poxy )
Array ( [0] => poxy [1] => alphy [2] => poxy [3] => alphy )
and when I try to save, it returns:
A Database Error Occurred
Error Number: 1054
Unknown column 'NDQA201303001' in 'field list'
INSERT INTO `coa_body` (`NDQA201303001`) VALUES ('')
Filename: C:\xampp\htdocs\NQCL\system\database\DB_driver.php
Line Number: 330
How should the syntax be so as to loop over all the textarea values and save them to the database at once?
I hope that
count($data) == count($data1); //Always True!
If that's the case the following will work:
for ($i=0;$i<count($data);$i++) {
$insert_data = array(
'labref'=>$labref, //NDQA201303001 - Same for all the rows
'compedia'=>$data[$i],
'specification'=>$data1[$i]
);
$this->db->insert('coa_body',$insert_data);
}
Check this Link: CodePad.org
Update:
Suggested by Rcpayan:
//This will reduce number of context switching,
//even though loping is doubled!
for ($i=0;$i<count($data);$i++) {
$insert_data[$i] = array(
'labref'=>$labref, //NDQA201303001
'compedia'=>$data[$i],
'specification'=>$data1[$i]
);
}
$this->db->insert_batch('coa_body',$insert_data);
You could do something like this, it's a bit longer but can also deal with compedia and specification not being equal. This solutions assumes a few things:
You want the value of labref to be the same for each row inserted
If the number of values for compedia and specification aren't equal, you still want to insert the row, but the 'missing' values will be set to NULL.
$labref = $this->uri->segment(3);
$compedia_data = $this->input->post('compedia');
$specification_data = $this->input->post('specification');
//Calculate which array is larger, so we can loop through all values
$max_array_size = max(count($compedia_data), count($specification_data));
//Iterate through the arrays
for ($i = 0; $i < $max_array_size; $i++)
{
$this->db->set('labref', $labref);
//If we still have a value(s) for compedia, then assign the value, otherwise set to NULL
if array_key_exists($i, $compedia_data)
{
$this->db->set('compedia', $compedia_data[$i]);
}
else
{
$this->db->set('compedia', NULL);
}
//If we still have a value(s) for specification, then assign the value, otherwise set to NULL
if array_key_exists($i, $specification_data)
{
$this->db->set('specification', $specification_data[$i]);
}
else
{
$this->db->set('specification', NULL);
}
//Insert into table: 'coa_body'
$this->db->insert('coa_body');
}
Alternatively, you could change the loop to assign the values to an array, then batch insert these values. This might offer better performance.
//Initial other relevant code is included in the example above (excluded here for brevity)
$insert_array = new array();
//Iterate through the arrays
for ($i = 0; $i < $max_array_size; $i++)
{
$row_array = new array();
$row_array['labref'] = $labref;
//If we still have a value(s) for compedia, then assign the value, otherwise set to NULL
if array_key_exists($i, $compedia_data)
{
$row_array['compedia'] = $compedia_data[$i];
}
else
{
$row_array['compedia'] = NULL;
}
//If we still have a value(s) for specification, then assign the value, otherwise set to NULL
if array_key_exists($i, $specification_data)
{
$row_array['specification'] = $specification_data[$i];
}
else
{
$row_array['specification'] = NULL;
}
//Add current row to the insert array, so it can be added to the database
$insert_array[$i] = $row_array;
}
//Insert into table: 'coa_body'
$this->db->insert_batch('coa_body', $insert_array);
I have a table like this:
id
name
parent_id
I then want to select certain rows based on their id, so something like this:
SELECT *
FROM TABLE
WHERE id IN ('1', '5', '8', '9', '35')
I want to, from this query, also show the parent/child relationship, like:
id parent
-----------
1 0
5 1
8 0
9 8
35 9
So the final output would look something like this:
1
--5
8
--9
----35
Do I do this outside of mysql, i have tried using arrays, but can't figure it out, or
Do I do it inside MYSQL, which i don't know how to do that either.
Here is what I was able to come with which seems to be working great.
PS-Sorry about the formatting, can't figure it out :( (fixed?)
I grab my parent_id and id from MYSQL and put it into an arraly where the array keys are the id's and the values are the parents, so with in the while loop for mysql, something like this: $testarray[$id] = $parent_id;
Then I run it through the functions below, and it orders it just how I need it.
function retrieveSubTree($parent, $myarray) {
$tempArray = $myarray;
$array = array();
//now we have our top level parent, lets put its children into an array, yea!
while ($child = array_search($parent, $tempArray)) {
unset($tempArray[$child]);
//now lets get all this guys children
if (in_array($child, $tempArray)) {
$array[$child] = retrieveSubTree($child, $tempArray);
} else {
$array[$child] = true;
}
}//end while
return (!empty($array)) ? $array : false;
}
function retrieveTree($myarray) {
$array = array();
$counter = 0;
foreach ($myarray as $key => $value) {
$child = $key;
$parent = $value;
//if this child is a parent of somebody else
if (in_array($child, $myarray) && $parent != '0') {
while ($myarray[$parent] != '' && $myarray[$parent] != '0') {
$newparent = $myarray[$parent];
$parent = $newparent;
}
if (!array_key_exists($parent, $array)) {
$array[$parent] = retrieveSubTree($parent, $myarray);
}
} else {
//now make sure they don't appear as some child
if (!array_key_exists($parent, $myarray)) {
//see if it is a parent of anybody
if (in_array($child, $myarray)) {
$array[$child] = retrieveSubTree($child, $myarray);
} else {
$array[$child] = true;
}
}//end if array key
}//end initial in array
}//end foreach
return (!empty($array) ? $array : false);
}
$test = array(
'1'=>'15',
'2'=>'1',
'3'=>'1',
'4'=>'0',
'5'=>'0',
'6'=>'4',
'7'=>'6',
'8'=>'7',
'9'=>'2',
'10'=>'9'
);
print_r(retrieveTree($test));
Without changing your table structure, this requires recursion, which MySQL does not support. You'll have to do it elsewhere. You can write a recursive function in PHP to use, for example, breadth-first search to build your array. Here it looks like you are using parent_id of 0 to denote a top-level object. You can search over your results, and add to your array every object whose parent is zero, which will give you an array with 1 and 8. Then you can recurse: find all the results with a parent of 1, and add that as a subarray to 1; then find all the results with a parent of 8 and add those as a subarray of 8. Continue doing this for each level until you've run out of results.
As other posters pointed out, you can do this natively in MySQL if you can change the table structure.