Foreach loop $key => $value - php

$suggestions = array();
$this->db->from('items');
$this->db->where('deleted',0);
$this->db->like('name', $search);
$this->db->limit($limit);
$by_name = $this->db->get();
$temp_suggestions = array();
foreach($by_name->result() as $row)
{
if ($row->category && $row->size)
{
$temp_suggestions[$row->item_id] = $row->name . ' ('.$row->category.', '.$row->size.')'.' Unit Price: '. $row->unit_price;
}
elseif ($row->category)
{
$temp_suggestions[$row->item_id] = $row->name . ' ('.$row->category.')'.' Unit Price: '.$row->unit_price;
}
elseif ($row->size)
{
$temp_suggestions[$row->item_id] = $row->name . ' ('.$row->size.')'.' Unit Price: '.$row->unit_price;
}
else
{
$temp_suggestions[$row->item_id] = $row->name.' Unit Price: '.$row->unit_price;
}
}
asort($temp_suggestions);
foreach($temp_suggestions as $key => $value)
{
$suggestions[]=array('value'=> $key, 'label' => $value); // Please take a look at this line
}
hi please see commented line, that foreach loop only display 2 columns from 9 columns, they are key and value. key contains ID and values display value of Qty column
So the question is:
how to modify this foreach loop to get ALL column of query with foreach loop?

The variable $temp_suggestions contains rows, not columns. To get all the data from each row, you must insert that data into $temp_suggestions in the prior loop. For example, to return all the columns as a comma-separated list indexed by the item_id:
foreach($by_name->result() as $row) {
$temp_suggestions[$row->item_id] = implode(', ', (array) $row);
}

Related

PHP Add New Line to Array Values Inside One Row and Column in Database Table

I managed to add multiple data in one column in the database, but now I need to display it with a new line in the browser so they don't stick with each other as I display them as an array in one column.
Here is my code:
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subArray = array("StudentAnswer");
$subId6 = $db->get("answertable", null, $subArray);
foreach ($subId6 as $sub) {
$answers[] = $sub['StudentAnswer'] . "\n";
}
foreach ($answers as $row) {
$answers2 = explode("||", $row[0]);
foreach($answers2 as $row2){
$answers3 = $row2 . '\n';
}
}
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers3);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}
You are overriding $subId6 after getting its content. Try to fetch the table $rows in a new variable and the extract the content from it, like the code below.
<?php
// Example of $subId6 content
$subId6 = array(["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]], ["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]]);
// Fetch rows
foreach ($subId6 as $sub) {
$rows[] = $sub['StudentAnswer'];
}
// Decode rows
foreach($rows as $row) {
$answers = explode("\n", $row[0]);
echo "New answers: \n";
// Split answers in single answer
foreach ($answers as $answer)
echo "$answer \n";
echo "\n";
}
You will have a list of all the answers split for table rows
If you want a string of answers seperated by a space then simply do
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subId6 = $db->get("answertable");
foreach ($subId6 as $sub) {
$answers .= $sub['StudentAnswer'] . ' ';
}
$answers= rtrim($answers, ' '); //remove last space in case thats an issue later
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}

Multi input & multi column for each loop PHP

Currently taking all get request through foreach function. Looking if column called season contains them. Next step is adding 1 more column to check if any get request is LIKE any of the next column values. The second column has to be an AND and not and OR, which means if the first column season contains any of the get requests AND the second column contains any of the GET requests.
Currently:
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%" . escape_string($value) . "%'";
};
$string = implode(' OR season LIKE ', $array_name);
$tank = "SELECT * FROM shrubs2 WHERE season LIKE {$string}";
echo $tank;
First edit:
function searchByColumn($values, $columnName) {
$string = implode(" OR $columnName LIKE ", $values);
return "SELECT * FROM shrubs2 WHERE $columnName LIKE $string";
}
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%".escape_string($value)."%'";
}
$colNames = array("season", "日照"); // can add here more column names
foreach($colNames as $colName) {
$str = searchByColumn($array_name, $colName);
}
echo $str;
///// creating the query with the variable $str
You can define function to search for each column:
function searchByColumn($values, $columnName) {
$string = implode(" OR $columnName LIKE ", $values);
return "SELECT * FROM shrubs2 WHERE $columnName LIKE $string";
}
Then use it as:
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%".escape_string($value)."%'";
}
$colNames = array("season"); // can add here more column names
foreach($colNames as $colName) {
$str = searchByColumn($array_name, $colName);
echo $str; // or run it
}

Function for PDO preapred stament not work and get error

I make 2 function with same use to take over PDO Preapred Statement, but both of not work .
Function 1 :
function doSave($array, $table) {
if (count($array) == 0) {
throw new Exception('Array cant be empty');
} else {
global $connect;
//prepare the query first
$prepare_1 = 'INSERT INTO' . ' ' . $table . ' '; //start preparing
$columns = array();
foreach ($array as $key => $value) {
$columns[] = ':' . $key; //gets all columns and add commas
}
foreach ($array as $key => $value) {
$keye[] = $key; //gets all columns and add commas
}
$keyes = implode(', ', $keye);
$column = implode(', ', $columns);
//now you can combine everything and prepare
$stmt99 = $connect->prepare($prepare_1 .'('.$keyes.')'. ' VALUES (' . $column . ')');
//remember to add the values. also test this section as its not tested
foreach ($array as $key => $value) {
$test[] = "':" . $key ."' => ". $value;
}
$tests = implode(', ', $test);
$stmt99->execute($tests);
}
}
When i insert the data i got no error and no data get insert to my database
Function 2 :
function doSave($array, $table) {
if (count($array) == 0) {
throw new Exception('Array cant be empty');
} else {
global $connect;
//prepare the query first
$prepare_1 = 'INSERT INTO' . ' ' . $table . ' '; //start preparing
$columns = array();
foreach ($array as $key => $value) {
$columns[] = ':' . $key; //gets all columns and add commas
}
foreach ($array as $key => $value) {
$keye[] = $key; //gets all columns and add commas
}
$keyes = implode(', ', $keye);
$column = implode(', ', $columns);
//now you can combine everything and prepare
$stmt99 = $connect->prepare($prepare_1 .'('.$keyes.')'. ' VALUES (' . $column . ')');
//remember to add the values. also test this section as its not tested
foreach ($array as $key => $value) {
$test[] = '$stmt99->bindparam('.'":' . $key .'",'. $value.'); ';
}
$tests = implode(' ', $test);
$tests;
$stmt99->execute();
}
}
i got error when use this function :
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
This How i use the function :
$array = array('categoryName' => $categoryName, 'categorySort' => $categorySort);
doSave($array, 'category');
This the source of the array :
if (!empty($_POST["categoryName"])) {
$categoryName = ($_POST["categoryName"]);
if (!preg_match("/^[a-zA-Z ]*$/",$categoryName)) {
$errMsg = "<div class='alert alert-danger text-center'><strong>Hanya boleh huruf.</strong></div>";
}
}
if ($_POST["categorySort"] == $check['categorySort']) {
$errMsg = "<div class='alert alert-danger text-center'><strong>Urutan sudah digunakan.</strong></div>";
}else{
$categorySort = ($_POST["categorySort"]);
if (!is_numeric($_POST['categorySort'])) {
$errMsg = "<div class='alert alert-danger text-center'><strong>Hanya boleh angka.</strong></div>";
}
}
What possibly go wrong from this 2 function both function for same use. Function 1 (named param) Function 2 (bindparam) ?
The following is not fully tested but displayed what I expected when I tested it using echo statements.
You should check the return value of prepare before attempting to execute the statement because it will return false if the statement failed to be prepared correctly.
function doSave( $array, $table ) {
try{
/* if you throw exceptions you should catch them!! */
if( empty( $array ) )throw new Exception('Array cant be empty');
if( empty( $table ) )throw new Exception('Table name cannot be empty');
global $connect;
/* placeholder variables */
$prepare = $columns = $values = array();
$result = false;
$table = preg_replace("#[',\.]#",'',$table);// whatever chars deemed appropriate to replace
$prepare[]="insert into `{$table}` ";
/* iterate through source array */
foreach( $array as $key => $value ) {
$columns[] = $key;
$values[ $key ] = $value;
}
$strcolumns = implode('`,`',$columns);
$strplaceholders = ':'.implode(', :',$columns);
/* append columns and placeholders */
$prepare[]="( `$strcolumns` ) values ( $strplaceholders );";
/* finalise sql statement */
$sql=implode('',$prepare);
$stmt = $connect->prepare( $sql );
if( $stmt ){
/* bind the params */
foreach( $values as $key => $value ) $stmt->bindParam( ':'.$key, $value );
/* execute the statement */
$result = $stmt->execute();
} else {
throw new Exception('Error preparing sql statement');
}
return $result;
}catch( Exception $e ){
exit( $e->getMessage() );
}
}
The assumption I made for the code was an input array like this
$t='mytable';
$a=array(
'id' => '303',
'name' => 'bob',
'size' => 'small',
'weight'=> 'heavy'
);
NOTE:
You have two functions both with the same name. How is PHP meant to know the which function you're calling?
Function 2:
foreach ($array as $key => $value) {
$test[] = '$stmt99->bindparam('.'":' . $key .'",'. $value.'); ';
}
Because you encased this in [single] quotes, this value is no longer an object method call but is just a string. This means that when you then implode this array all you're making is a longer string.
Also, because you're using single quotes, PHP will not recognise the value $stmt99 as being a PHP object reference, instead taking it literally as dollar sign, s character, t character, m character, etc....
So PDO has no values to bind into the SQL given.
Fix:
foreach ($array as $key => $value) {
$stmt99->bindparam(":" . $key , $value);
}
unset($key,$value); // always tidy up after foreach loops.
A better fix can be found exampled here

Help with PHP loop

Suppose I have a multi-dimensional array of the form:
array
(
array('Set_ID' => 1, 'Item_ID' => 17, 'Item_Name' = 'Whatever'),
array('Set_ID' => 1, 'Item_ID' => 18, 'Item_Name' = 'Blah'),
array('Set_ID' => 2, 'Item_ID' => 19, 'Item_Name' = 'Yo')
)
The array has more sub-arrays, but that's the basic form-- Items in Sets.
How can I loop through this array so that I can echo the number of items in each set along with the all the items like so:
Set 1 has 2 Items: 17: Whatever and 18: Blah
Set 2 has 1 Items: 19: Yo
I'm aware that this could be done with two loops-- one to build an array, and another to loop through that array. However, I'd like to do this all with only one loop.
In your answer, you should assume that there are two display functions
display_set($id, $count) //echo's "Set $id has $count Items"
display_item($id, $name) //echo's "$id: $name"
UPDATE: Forgot to mention that the data is sorted by Set_ID because its from SQL
Right, all the examples below rely on an ordered set, the OP states it is ordered initially, but if needed a sort function could be:
// Sort set in to order
usort($displaySet,
create_function('$a,$b',
'return ($a['Set_ID'] == $b['Set_ID']
? ($a['Set_ID'] == $b['Item_ID']
? 0
: ($a['Item_ID'] < $b['Item_ID']
? -1
: 1))
: ($a['Set_ID'] < $b['Set_ID'] ? -1 : 1));'));
Straight example using a single loop:
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item display for later
ob_start();
display_item($cItem['Item_ID'], $cItem['Item_Name');
$cSetEntries[] = ob_get_clean();
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
Using a recursive function it could be something like this:
// Define recursive display function
function displayItemList($itemList) {
if (!empty($itemList)) {
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name');
if (!empty($itemList)) {
echo " and ";
}
}
displayItemList($itemList);
}
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item for later
$cSetEntries[] = $cItem;
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
Amusingly, it can be one single recursive function:
function displaySetList($setList, $itemList = NULL) {
// First call, start process
if ($itemList === NULL) {
$itemList = array(array_shift($setList));
displaySetList($setList, $itemList);
return;
}
// Check for display item list mode
if ($setList === false) {
// Output first entry in the list
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name']);
if (!empty($itemList)) {
// Output the next
echo " and ";
displaySetList(false, $itemList);
} else {
echo "\n";
}
return;
}
if (empty($setList) || $setList[0]['Set_ID'] != $itemList[0]['Set_ID']) {
// New Set detected, output set
display_set($itemList[0]['Set_ID'], count($itemList));
echo ": ";
displaySetList(false, $itemList);
$itemList = array();
}
// Add next item and carry on
$itemList[] = array_shift($setList);
displaySetList($setList, $itemList);
}
// Execute the function
displaySetList($displaySet);
Note that the recursive example here is grossly inefficient, a double loop is by far the quickest.
<?php
$sets = array();
foreach ($items as $item)
{
if (!array_key_exists($item['Set_ID'], $sets))
{
$sets[$item['Set_ID']] = array();
}
$sets[$item['Set_ID']][] = $item;
}
foreach ($sets as $setID => $items)
{
echo 'Set ' . $setID . ' has ' . count($items) . ' Items: ';
foreach ($items as $item)
{
echo $item['Item_ID'] . ' ' . $item['Item_Name'];
}
}
?>
Something like this i guess?
EDIT:
After i posted this i saw the display functions where added. But you get the point.
The need to not print out any items until we know how many there are in the set makes this difficult. At some point, we'll need to doing some buffering, or else backtracking. However, if I'm allowed internal loops, and sets are contiguous in the "master" array, then with some hacking around:
$set = 0;
$items;
foreach ($arr as $a) {
if ($a['Set_ID'] != $set) {
if ($set != 0) {
display_set($set, count($items));
foreach ($items as $i)
display_item($i)
}
$set = $a['Set_ID'];
$items = array();
}
$items[] = $a;
}
How about this:
$previous_set = false;
$items = '';
$item_count = 0;
foreach ($rows as $row)
{
if ($row['Set_ID'] != $previous_set)
{
if ($previous_set)
{
echo display_set($row['Set_ID'], $item_count);
echo $items;
}
$previous_class = $row['Set_ID'];
$item_count = 0;
$items = '';
}
$items .= display_item($row['Item_ID'], $row['Title']);
$item_count++;
}
echo display_set($row['Set_ID'], $item_count);
echo $items;

PHP: high depth array, how do return current key name?

I have a huge array from a json_decode result (assoc set to true) and have the following code to check if (one of the arrays within, a random serial) has the key 'set_true'
$out = "";
foreach ($array as $sub) {
//$out[] = $sub['set_true'];
if (in_array($sub['set_true'], $sub) && $sub['set_true'] == '1' ) {
$out[] = 'User: ' . $sub . ' has set_true = 1';
}
}
That code lists all the users with that array key set to 1, but $sub returns 'array' and not the current key I'm on! (the random serial)
How do I return it?
If you are looping through an array with foreach, and want to know the key you're currently on in the loop, you can use this syntax :
foreach ($array as $key => $value) {
// $key contains the name of the current key
// and $value the current value
}
What's up with your in_array call? I don't think that is correct. Why do you look for $sub in $sub?
I think you mean:
$out = "";
foreach ($array as $key => $sub) {
if (array_key_exists('set_true', $sub) && $sub['set_true'] == '1' ) {
$out[] = 'User: ' . $key . ' has set_true = 1';
}
}

Categories