Multidimensional session array printing the elements by using echo function - php

I have piece of code that I need to use echo function in order to print the variables inside the session array, on the other hand I need to add prices one by one every time user chooses a product. The prices variable is a string. The code as follows:
if (!is_array($_SESSION['products']['names'])){
$_SESSION['products']['names']['name'] = array();
$_SESSION['products']['names']['prices']= array();
}else {
$pros = $_SESSION['products']['names']['name'];
if (in_array($product->getName(), $pros, true)){
echo 'The product is available in your basket';
} else {
$prozuct = array_push($_SESSION['products']['names']['name'],$product->getName());
array_push($_SESSION['products']['names']['prices'], $product->getPrice(Currency::getCurrentCurrency()));
foreach ($_SESSION['products'] as $id=>$arr){
for ($i=0;$i<count($arr);$i++){
echo $arr['name'][$i];
}
}
}
}
The error that I receive is:
Notice: Undefined offset: 1 in /Users
And additionally I know that I can use print_r but in my case I want to add prices one by one and calculate and show the total of amount to user.

No need for a loop:
$namesHtml = implode("<br>", $_SESSION['products']['names']['name']);
$total = array_sum($_SESSION['products']['names']['price']);
echo sprintf("<p>Products: <br>%s<br>Total Cost: %s", $namesHtml, $total);

Related

MVC multi-dim array displaying in view

I can't think my way through this one. I'm still learning arrays so go easy on me. I'm using codeigniter.
I have 3 tabs (1 month, 2 month, 3 month) in my mark-up.
Each tab shows 3 price boxes (3 levels - basic=1, standard=2, featured=3).
I need to display 9 prices overall, pulled from 1 look-up:
return $this->db->get('prices')->result_array();
In the database it's like this
Should I be trying to do it from one look-up as shown in my model or should I be doing several look-ups, or should I just be managing that look-up in the controller setting vars, ready to display in the view or just doing everything in the view? And How? The only think of 3x foreach loops, where inside the loop I say:
if($prices['months']==3) echo $prices['level'].' is '.$prices['amount'].'<br>';
I'd like to know the BEST way to do this but also how to do the array from one look-up, because I think I really need to get my head around arrays properly. Thanks :)
-- EDIT to show what I've ended up using below --
In the controller, sort of inspired by array_chunk but more manual and to allow for the table to expand, is setting array keys which I read up on in php manual:
foreach ($prices as $price_row) {
$data['prices'][$price_row['months']][] = $price_row;
}
Then in the view I can just use foreach for a month:
foreach ($prices[1] as $p) {
echo level_name($p['level']).' = '.$p['amount'].'<br>';
}
i did not test this so might have made a stupid error - but basically you can foreach through each of your products - make an array - and then use that array in your view.
// in your model Note I am returning an object not an array
// and always check to make sure something got returned
if( ! $products = $this->db->get('prices')->result() )
{
return false:
}
else
{
$prices = array();
foreach($products as $product)
{
// append the months number to the word 'months' to make it clear
$month = $product->months . 'month' ;
// same with level
$level = 'level' . $product->level ;
// build the array
$prices[$month][$level] = $product->amount ;
}//foreach
return $prices ;
}//else
so then in your controller - make sure something came back from the model, assign it to data, then pass data to your view
if( ! $data['prices'] = $this->somemodelname->returnPrices() )
{
$this->showError() ;
}
else
{
$this->load->view('yourviewname', $data);
}
and then in your view you could foreach or just echo out each price if it needs to follow some layout.
echo '1 month level 1 $' . $prices['1month']['level1'] ;
and remember your best friend when doing arrays is print_r wrapped in pre tags so like
echo 'start prices <br> <pre>' ;
print_r($prices) ;
echo '</pre>' ;
opinions - its fine to build stuff in the controller and the view while you are developing and building out. but get in the habit of refactoring to your models. keep your controllers as clean and thin as possible. if your views need complicated data structures - build them in a model first. that way if something goes wrong - your controller can decide what to do. AND you don't have to check in your view if $prices is set and valid because you have already done it. this minimizes where things can go wrong.
Here's a pretty easy way to sort the db return into separate arrays and then display them. #caralot stole my thunder so I came up with this alternative.
Using your current model return $this->db->get('prices')->result_array(); and assigning it to $data.
$data = $this->db->functionName();
//You should check $data validity but I'm skipping that
$month1 = [];
$month2 = [];
$month3 = [];
foreach($data as $row)
{
if($row['months'] === '1')
{
$month1[] = $row;
}
elseif($row['months'] === '2')
{
$month2[] = $row;
}
else
{
$month3[] = $row;
}
}
echo "Month 1<br>";
foreach($month1 as $month){
echo "Level ". $month['level'].' is '.$month['amount'].'<br>';
}
echo "Month 2<br>";
foreach($month2 as $month){
echo "Level ".$month['level'].' is '.$month['amount'].'<br>';
}
echo "Month 3<br>";
foreach($month3 as $month){
echo "Level ".$month['level'].' is '.$month['amount'].'<br>';
}
If your table was less ordered than what you show it would be necessary to add a $this->db->order_by('level', 'ASC'); call to the query.
It is such a tiny dataset that you should definitely do a single lookup. Sorting the array into three arrays in your controller would make more sense as it will leave your view much cleaner, and allow you to set defaults should there be no data (say level 1 for 3 months is removed) if you need to. You are always going to need three foreach loops unless you construct the entire table in one go, setting breaks and new column headings when the level indicator changes.
There is no 'Best' way to do this, it is all case dependent on complexity of layout, future data development and your requirements. Usually though you minimize the number of queries, and keep data manipulation to a minimum within you views. So ideally you will have three arrays, one for each column, sent to your view.
In your controller,
$result = $this->db->query("SELECT * from prices");
$result=$result->result();
$tab1=array();
$tab2=array();
$tab3=array();
foreach ($result as $res) {
switch($res->months)
{
case 1: array_push($tab1, $res);
break;
case 2: array_push($tab2, $res);
break;
case 3: array_push($tab3, $res);
break;
}
}
//var_dump($tab3); //array tab1 for month1, array tab2 for month2, array tab3 for month3
$data['tab1']=$tab1;
$data['tab2']=$tab2;
$data['tab3']=$tab3;
$data['include']=$this->load->view('myview', $data);
In your view i.e myview in my case,
<?php
if(!empty($tab1))
{
echo "Tab 1"."<br>";
foreach($tab1 as $tb)
{
echo "For level ".$tb->level." price is ".$tb->amount."<br>";
}
}
if(!empty($tab2))
{
echo "Tab 2"."<br>";
foreach($tab2 as $tb)
{
echo "For level ".$tb->level." price is ".$tb->amount."<br>";
}
}
if(!empty($tab3))
{
echo "Tab 3"."<br>";
foreach($tab3 as $tb)
{
echo "For level ".$tb->level." price is ".$tb->amount."<br>";
}
}
?>

Invalid argument supplied for foreach() for shopping cart$_SESSION['cart']

if (isset($_GET['addCart'])&& is_numeric($_GET['addCart']))
{
$item = $_GET['addCart'];
$_SESSION ['cart'][$item] = $item;
echo "<h3 class=change> Item ".$item." has been added to cart.</h3>";
foreach($_SESSION['cart'] as $myItem)
{
echo "<br>item: ".$myItem."<br>";
}
}
I can't display the items in the shopping cart.
When I run this code, I get a Warning: Invalid argument supplied for foreach().
EDIT:
However, this works fine:
$_SESSION['shoppingCart'] = array();
$_SESSION['shoppingCart']['1'] = 2;
$_SESSION['shoppingCart']['2'] = 3;
//get all items
foreach($_SESSION['shoppingCart'] as $item)
{
echo"<br>contents of shoppingcart ".$item."<br>";
}
EDIT
Session is started.
I think it has to do with this line:
$_SESSION ['cart'][$item] = $item;
I tried these two and it doesn't work:
`$_SESSION ['cart']['$item'] = $item`;
`$_SESSION ['cart'][] = $item`;
error for first one: Warning: Illegal string offset '$item'
error for second one: Fatal error: [] operator not supported for strings
foreach is used for keyed arrays. If $_SESSION['cart'] is not a keyed array, use a for loop instead.
for ($i=0;$i<count($_SESSION['cart']);$i++){
echo "$_SESSION['cart'][$i]";
}
Well, this depends on how your cart items are stored in $_SESSION['cart']
If $_SESSION['cart'] contains an array of items, you should do something like this:
$items = $_SESSION['cart'];
for($i=0; $i<count($items); $i++)
{
echo $items[$i].'<br />';
}
Your code works fine for me.
Please check if your php session config is ok. Use phpinfo() and check the session.* config, look for session.save_path - check if you have this director and your web server is able to write there.
Also try to put: session_start(); at the beginnig of the script.
You should try initializing the cart index of the session
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
Before you try to add items to it. Also be sure to start your session using the session_start() function

fetch data from model that is called in loop

I have a controller function in CodeIgniter that looks like this:
$perm = $this->job_m->getIdByGroup();
foreach($perm as $pe=>$p)
{
$pId = $p['id'];
$result = $this->job_m->getDatapermission($pId);
}
$data['permission'] = $result;
What I need to do is list the data in the result in the view, but I get only the last value while using this method. How can I pass all the results to the view?
Store it in an array. Like this:
foreach($perm as $pe=>$p){
$result[] = $this->job_m->getDatapermission($p['id']);
}
Because $result is not an array...
try this:
$result=array();
foreach($perm as $pe=>$p)
{
$pId = $p['id'];
$result[] = $this->job_m->getDatapermission($pId);
}
$data['permission'] = $result;
Note:
My answer uses a counter to enable the display of a single group result when needed.
Guessing from your need to loop and display the value of $result, possibly, it is an array or object returned by $query->result(). Things could be a bit complex.
Example: if $perm is an array of 5 items( or groups), the counter assigns keys 1 - 5 instead of 0 - 4 as would [] which could be misleading. Using the first view example, you could choose to display a single group value if you wants by passing it via a url segment. Making the code more flexible and reusable. E.g. You want to show just returns for group 2, in my example, $result[2] would do just that else next code runs. See my comments in the code.
$perm = $this->job_m->getIdByGroup();
$counter = 1;
foreach($perm as $pe=>$p)
{
$pId = $p['id'];
$result[$counter] = $this->job_m->getDatapermission($pId);
$counter++;
}
$data['permission'] = $result;
As mentioned above Note:
I Added a Counter or Key so you target specific level. If the groups are:
Men, Women, Boys, Girls, Children; you'd know women is group two(2) If you desire to display values for just that group, you don't need to rewrite the code below. Just pass the group key would be as easy as telling it by their sequence. To display all the loop without restrictions, use the second view example. To use both, use an if statement for that.
###To access it you could target a specific level like
if(isset($permission)){
foreach($permission[2] as $key => $value){
echo $value->columnname;
}
###To get all results:
foreach($permission as $array){
foreach($array as $key => $value){
echo $value->columnname;
}
}
}

Removing an item from shopping cart array

I'm building a shopping cart, I save the orders in a multidimensional array which is stored in a session, $_SESSION['cart']
A product is represented by something like
$product_array=array($id,$description,$price);
The multidimensional array is the array of the $product_array.s
The $id's are unique.
The issue is, When i want to remove a product from the multidimensional $_SESSION['cart']
array based on the id, it works if it's just one item in the cart, but if more, it doesn't work, the items seems to be removed but it's 'ghost' is left behind in the cart. The code
is something like this :
//get $id, $count is elements in array
for ($r = 0; $r <= $count-1; $r++)
{
if($_SESSION['cart'][$r][0]=="$id")
{
unset($_SESSION['cart'][$r]);
echo "<div class=success>The item has been removed from your shopping cart.</div>";
break;
}
}
try this one function and that is working for me
function remove_product($id){
$id=intval($id);
$max=count($_SESSION['cart']);
for($i=0;$i<$max;$i++){
if($id==$_SESSION['cart'][$i]['id']){
unset($_SESSION['cart'][$i]);
break;
}
}
$_SESSION['cart']=array_values($_SESSION['cart']);
if($_REQUEST['command']=='delete' && $_REQUEST['id']>0){
remove_product($_REQUEST['id']);
}
else if($_REQUEST['command']=='clear'){
unset($_SESSION['cart']);
}
else if($_REQUEST['command']=='update'){
$max=count($_SESSION['cart']);
for($i=0;$i<$max;$i++){
$id=$_SESSION['cart'][$i]['id'];
$q=intval($_REQUEST['qty'.$id]);
if($q>0 && $q<=999){
$_SESSION['cart'][$i]['qty']=$q;
}
else{
$msg='Some proudcts not updated!, quantity must be a number between 1 and 999';
}
}
}
Check if register_global is on in your php.conf. Try to use following syntax to unset both:
if($_SESSION['cart'][$r][0]=="$id") {
$_SESSION['cart'][$r] = NULL;// this is just to be sure =)
unset($_SESSION['cart'][$r], $cart[$r]);
echo "<div class=success>The item has been removed from your shopping cart.</div>";
break;
}
The following code works, maybe it will help You find what's wrong with Yours:
session_start();
$i=0;
$_SESSION['cart'][]=array($i++,'sds',99);
$_SESSION['cart'][]=array($i++,'sds',100);
$_SESSION['cart'][]=array($i++,'sds',20);
$_SESSION['cart'][]=array($i++,'sds',10);
$id = 2;
$count = count($_SESSION['cart']);
for ($r=0;$r<$count;$r++)
{
echo "num=$r<br>";
if(isset($_SESSION['cart'][$r]) && $_SESSION['cart'][$r][0]==$id)
{
unset($_SESSION['cart'][$r]);
echo "The item has been removed from your shopping cart.<br>";
break;
}
}
session_write_close();
As stated I think the issue has to do with the layout of your array and what you try to check against in your for loop or perhaps some PHP setting. Have you initiated a session for example? I would probably move to use an array of product references. Working with plain arrays can quickly become a nightmare where you accidently reference the wrong object without any kind of warning etc. Encapsulated objects fetched with well formed function names helps avoid this.
Something like
$cart = array($productId => $quantity, $productId2 => $quantityOfSecondProduct);
And then have an array that has all the product info data
$products = array($product1...);
where each product is of the type
class Product
{
$productId;
$productName;
$productDescription;
... etc
}
Then you have all the data separated but easily accessible and you can delete one or more entries in the cart based on the products id easily but just referencing it and deleting if quantity is 0.
if(($cart[$productId] - $quantityToRemove) <= 0)
unset($cart[$productId]);
else
$cart[$productId] -= $quantityToRemove;
Note that filling the products etc should preferably be done from some data source, I would also have put the entire cart as a class with nice functions and a bit more error checking should be in place ;)

php: add array placement number to each array set e.g. 1 2 3

I have a data set from mysql in a multidimensional array.
I am using a pagination script to show 10 per page of that array. I want to know how to append a number to each one like a scoring system. The array is sorted by the way that it will aways be so i want to to add a 1 to the first item, a 2 to the second item and so on.
I dont want to do this in the foreach that i output since this will not translate over to the second page where it would start back at 1.
Any ideas on how to attach a number in desc order to each item in the array so i can access it in the foreach and display it?
Thanks in advance
Use the same math used to find the offset in your pagination query and start counting from there.
fist you need to save the indexes in a $_SESSION variable:
$_SESSION['indexes'] = array();
and for multidimentional:
foreach( $array as $index=>$arrValue) {
echo $index;
foreach($arrValue as $index2=>$value){
echo $index2;
$_SESSION['indexes'][$index][$index2] = $value;
echo $value;
}
}
than you can go through all of the session indexes; where $index is the page or $index2 can be the row
I figured it out by doing some calculations based on which page i was on and the page count that was set and finding the size of the array from the db:
$all_members = get_users_ordered_by_meta('metavalue', 'desc');
$array_count = count($all_members);
$posts_per_page = get_option('posts_per_page');
if ($page > 0) {
$total_posts_avalible = ($posts_per_page * $page);
$usernum = $total_posts_avalible - $posts_per_page;
}
Then i echo the $usernum in the foreach next to the name of the user.
foreach() {
$usernum++;
echo $usernum; echo $user_name;
}

Categories