The output should look like this:
1. Yougurt 4 units price 2000 CRC
But I'm currently getting this:
item. Y Y unitsYquantity. 3 3 units3code. S S unitsSprice. units
This is the script:
<?php
session_start();
//Getting the list
$list[]= $_SESSION['list'];
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$_SESSION['list'] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
//price
$price = $products[($_SESSION['list']['item'])] * $_SESSION['list']['quantity'];
$_SESSION['list']['price'] = $price;
//listing
echo "<b>SHOPPIGN LIST</b></br>";
foreach($_SESSION['list'] as $key => $item)
{
echo $key, '. ', $item['item'], ' ', $item['quantity'], ' units', $item['price'];
}
//Recycling list
$_SESSION['list'] = $list;
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
print_r($_SESSION);
?>
The problem is that you are nested 1 level deeper in the arrays than you think you are. To make it clear, the $_SESSION may look lik this (just before entering the foreach):
array(1) {
["list"] => array(3) {
["item"] => string(8) "Pineaple"
["quantity"] => int(30)
["price"] => int(15000)
}
}
(you can use var_dump($var) or print_r($var) methods to see the value: http://php.net/manual/en/function.var-dump.php http://php.net/manual/en/function.print-r.php)
When iterating over $_SESSION["list"], you pass the loop 3 times. In the first iteration, $key is "item", $value "Pineaple".
echo $key, '. ', $item['item'], ' ', $item['quantity'], ' units', $item['price'];
"item . P P units <empty>"
Why?
String "item" is obvious, it's just printed out.
$item['item'] -> 'item' is cast to (int)0, so the first character of $item (Pineaple) is printed: P
(The examples of string->int conversion rules are for example here: http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion)
$item['quantity'] -> the same as above
$item['price'] -> since the price is much higher than the length of the string, empty string is printed:
$myvar = "hi";
echo $myvar[12234]; // prints empty string
In every iteration you get this output, just the first word is changing. Put echo "<br />" at the end of the iteration and you will see it.
I hope this helps you a bit.
Related
I have been researching comparing two associative arrays, which I have only been able to do with a fair degree of accuracy. I have read all similar threads on S.O. but none have solved or addressed the issue I am having, which is, while comparing two associative arrays the test data will successfully show the appropriate matches, however when I attempt to count the number of matched values, I am getting some strange results.
EDIT:
<?php
$data = array(
'Alpha' => array(
'peace' => 0,
'art' => 1,
'trend' => 0,
'night' => 1,
'shop' => 0
),
'Beta' => array(
'peace' => 1,
'art' => 1,
'trend' => 1,
'night' => 1,
'shop' => 0
),
'Gamma' => array(
'peace' => 0,
'art' => 1,
'trend' => 1,
'night' => 1,
'shop' => 0
)
);
$choices = array(
'peace' => 0,
'art' => 1,
'trend' => 0,
'night' => 1,
'shop' => 0
);
function compare($data, $choices)
{
foreach ($data as $city => $name)
{
echo $city . '<br>';
foreach ($name as $key => $value)
{
($choices[$key] === $value) ? $match = 'match' : $match = 'no';
($choices[$key] === $value) ? $i++ : $i = 0;
echo $key . ':' . $value . ':' . $choices[$key] . ':' . $match . '<br>';
}
echo 'Matches:' . $i . '<br><br>';
}
}
compare($data, $choices);
?>
OUTPUT DATA
Format of data is as follows
-----------------------------
name of key:$data value:$choices value:is match
Alpha
peace:0:0:match
art:1:1:match
trend:0:0:match
night:1:1:match
shop:0:0:match
Matches:5
Beta
peace:1:0:no
art:1:1:match
trend:1:0:no
night:1:1:match
shop:0:0:match
Matches:2
Gamma
peace:0:0:match
art:1:1:match
trend:1:0:no
night:1:1:match
shop:0:0:match
Matches:2
'Alpha' should return 5 matches, which it does.
'Beta' should return 3, it returns 2.
'Gamma' should return 4, it returns 2.
Any help would be greatly appreciated. Thank you in advance.
The problem is how you are incrementing the count with a ternary statement. When you do
($choices[$key] === $value) ? $i++ : $i = 0;
It will reset $i to zero any time it encounters a non-match.
Using a simple conditional instead should give you the correct count.
if ($choices[$key] === $value) $i++;
You can initialize $i to 0 before the inner foreach loop.
im trying to remove a complete level in an array
all the items starting with [1]
i am having no luck with arrays at all. kinda new to me. and reading all the stuff i find is not clear nor example like mine.
heres my code so far. i can remove the submit. but i cant go any farther plus im not sure how to remove all of them in heading,special,item, etc as item [1] - regular caesar salad
thank you for any help you may provide
code
<?php
// version:
$testarray =
Array(
"heading" => Array
(
"0" => 'Salads',
"1" => 'Salads',
"2" => 'Pasta',
),
"special" => Array
(
"0" => '',
"1" => '',
"2" => '',
),
"item" => Array
(
"0" => 'Small Green',
"1" => 'Regular Caesar',
"2" => 'Baked Lasagna',
),
"description" => Array
(
"0" => 'Grape tomatoes, onions, green peppers and cucumbers on the bed of crisp lettuce.',
"1" => 'Classic recipe with romaine lettuce and croutons',
"2" => 'With meat sauce, tomato vegetarian sauce or Alfredo sauce',
),
"price" => Array
(
"0" => 'See Desc',
"1" => '$5.99',
"2" => '$9.69',
),
"notes" => Array
(
"0" => 'Available in Small ($2.99), Regular ($5.99)',
"1" => '',
"2" => '',
),
"submit_val" => 'Submit'
);
echo "testarray";
echo "<pre>";
print_r($testarray);
echo "</pre>";
echo "<hr>";
$removed_data=removeItem($testarray,'Submit');
echo "removed_data";
echo "<pre>";
print_r($removed_data);
echo "</pre>";
echo "<hr>";
die();
// works for submit
function removeItem($look_in_Array, $remove){
foreach($look_in_Array as $key => $value) {
echo $key . ' = ' . $value . '<br>';
if ($value ==$remove) {
echo 'found '.$remove."<br>";
unset($look_in_Array[$key]);
}
}
return $look_in_Array;
}
?>
output desired?:
sample of desired output
$testarray =
Array(
"heading" => Array
(
"0" => 'Salads',
"1" => 'Pasta',
),
"special" => Array
(
"0" => '',
"1" => '',
),
"item" => Array
(
"0" => 'Small Green',
"1" => 'Baked Lasagna',
),
"description" => Array
(
"0" => 'Grape tomatoes, onions, green peppers and cucumbers on the bed of crisp lettuce.',
"1" => 'With meat sauce, tomato vegetarian sauce or Alfredo sauce',
),
"price" => Array
(
"0" => 'See Desc',
"1" => '$9.69',
),
"notes" => Array
(
"0" => 'Available in Small ($2.99), Regular ($5.99)',
"1" => '',
),
"submit_val" => 'Submit'
);
If I understand your question correctly, you're looking to remove any array key [1]. If you're doing this as a function anyway, you can either use unset or declare and return a new array. Using unset() might be what you're looking for, but it is sort of a waste of time in a function because it only passes a local variable. Instead, you may want to pass values onto a new array. Please note that this will retain key values.
function removeItemsRecursive($array,$searchKey) {
/*
** Finds any key value that equals $searchKey
** in a multi-level array and does not pass anything
** equal to $searchKey.
*/
foreach($array AS $key=>$value) { //go through each array and assign [key] => value to $key and $value, respectively
if($key !== $searchKey) //if a key is not equal to the $searchKey (aka 1 for example) then assign something to $newArray
{
if(is_array($value)) //if the value inside of the array is another array (for multilevel arrays)
{
$newArray[$key] = removeItemsRecursive($value,$searchKey); //loop through the function and do this for the next level down.
}
else //if the value inside of the array is scalar
{
$newArray[] = $array[$key]; //the new array is assigned the current value where the array key is not equal to $searchKey.
}
}
}
return $newArray;
}
This will essentially go through each value of the $array and pass that value to $newArray if the $key is not $searchKey, aka removeItemsRecursive($array,1); will return a new array without any values with the key being 1.
Calling the Function
To call the function, simply add:
$array = removeItemsRecursive($testarray,1);
When looking at this new array, you will see the results you're looking for.
echo "<PRE>";
print_r($array);
echo "</PRE>";
//returns the array you're looking for.
http://php.net/manual/en/function.unset.php
use unset function in php. in your case you could just iterate over the array and remove all the element at position 1.
function removeLevel($a, $l) { // $a = entire array, $l = level to remove
$removed = array();
foreach ($a as $inner) { // iterate through the outer array
array_splice($inner,$l,1); // remove the "$l"th element of the $inner array
}
return $a; // return new array with level removed
}
$arrBetter = removeLevel($testarray, 2) will return the array with that level of data removed!
<?php $student = array(
1 => array(
"firstname" => "first",
"name" => "first",
"group" => "grp01",
"score" => array(
"ASP" => 86,
"PHP" => 79,
"JAVA" => 72,
"HTML" => 96,
"JAVASCRIPT" => 98,
"VBNET" => 66
)
),
2 => array(
"firstname" => "second",
"name" => "second",
"group" => "grp01",
"score" => array(
"ASP" => 80,
"PHP" => 70,
"JAVA" => 71,
"HTML" => 92,
"JAVASCRIPT" => 90,
"VBNET" => 78
)
),
3 => array(
"firstname" => "third",
"name" => "third",
"group" => "grp02",
"score" => array(
"ASP" => 88,
"PHP" => 88,
"JAVA" => 89,
"HTML" => 96,
"JAVASCRIPT" => 98,
"VBNET" => 71
)
) ); ?>
<?php
foreach($student as $std) {
foreach($std as $key => $p){
echo $std[$key];
} } ?>
i am trying to print in echo each student with they average score but right now i am stuck i got a warning about array to string convertion can someone give me some hint how i am suppose to do my loop.
Use PHP-functions to calculate the average for every student, rounded to two digits:
foreach($student as $std) {
$avg = round(array_sum($std['score']) / count($std['score']), 2);
echo $std['name']. ": $avg <br />";
}
see it working: http://codepad.viper-7.com/RBINCd
You are iterating the wrong array, once inside each student you must iterate over the "score", if not you were trying to convert the score array to a string:
foreach($student as $std) {
foreach($std["score"] as $language => $score) {
echo $score;
}
}
The error you are getting comes when you try to echo the "score" portion of the array. As it is itself an array it cannot be echo'd out in this way.
You will need another loop to add up the scores, then get the average outside of it.
Something along the lines of:
foreach($student as $std) {
foreach($std as $key => $p){
if ( $key === 'score'){
$avg = 0;
foreach( $p as $score){
$avg += $score;
}
$avg = ($avg/size_of($p));
}
}
}
I'm using two arrays, one is a POST string (product), and another is a predefined set of values(products).
They work together as:
$products[$_POST['product']]
This is okay if the POST value is exactly one of the following:
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
Otherwise it will pop Undefined Index messages. Since this is a SESSION, I need to somehow keep a list of items, but remove the invalid ones from the array and echo a message.
Please check the screenshot: http://img36.imageshack.us/img36/9121/20110430004019.jpg
This is the script I'm using:
<?php
session_start();
//Getting the list
$_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$new_item = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
$new_product = true;
foreach($_SESSION['list'] as $key => $item) {
if ($item['item'] == $new_item['item']) {
$_SESSION['list'][$key]['quantity'] += $new_item['quantity'];
$_SESSION['list'][$key]['price'] =
$products[$new_item['item']] * $new_item['quantity'];
$new_product = false;
}
}
if ($new_product) {
$_SESSION['list'][] = $new_item;
}
//listing
echo "<b>SHOPPING LIST</b></br>";
foreach($_SESSION['list'] as $key => $item) {
echo 'Product .'. $key. ' '. $item['item'], ' ',
$item['quantity'], ' units: ', $item['price']. '<br />';
}
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
var_dump($_SESSION);
//session_destroy();
?>
You should use isset or array_key_exists to check whether the key exists before reading it:
if (isset($products[$_POST['product']])) {
// product in stock
} else {
// product not in stock
}
And if you use the same key for your product list in $_SESSION['list'], you don’t need to iterate the whole list to find the same product in the list:
if (isset($_SESSION['list'][$_POST['product']])) {
// update product in list
$_SESSION['list'][$_POST['product']]['quantity'] += $_POST['quantity'];
$_SESSION['list'][$_POST['product']]['price'] = $products[$_POST['product']] * $_POST['quantity'];
} else {
// add product to list
$_SESSION['list'][$_POST['product']] = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
}
Note that this will always only add items to the list. You should add some functionality to also update and remove items. And don’t forget to validate the data before using it (e.g. so that people don’t get refund if they enter a negative quantity).
I would imagine you want to use the array_intersect_assoc function. it returns the items that are in both of your arrays.
This data comes from a POST form, the idea is to simply add more lines whenever a new product is added.
The current output is:
l. Banana 3 units: 150
Please take a look into the script (specially the foreach loop):
<?php
session_start();
//Getting the list
$list= $_SESSION['list'];
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$_SESSION['list'] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
//price
$price = $products[($_SESSION['list']['item'])] * $_SESSION['list']['quantity'];
$_SESSION['list']['price'] = $price;
//listing
echo "<b>SHOPPIGN LIST</b></br>";
foreach($_SESSION as $key => $item)
{
echo $key[''], '. ', $item['item'], ' ', $item['quantity'], ' units: ', $item['price'];
}
//Recycling list
$_SESSION['list'] = $list;
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
var_dump($_SESSION);
?>
change this code:
//Saving the stuff
$_SESSION['list'] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
to
//Saving the stuff
$_SESSION['list'][] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
and remove this code:
//Recycling list
$_SESSION['list'] = $list;
Now, you'll get a new entry in $_SESSION every time you POST to the page.
Also, if you want your output to look like:
l. Banana 3 units: 150
2. Orange 5 units: 250
etc
then you'll need to change the echo in the foreach() loop from
echo $key[''] . // everything else
to just
echo ($key+1) . // everything else
Since key will be your array index starting at 0, you'll need to do a +1 every iteration, otherwise your list would look like
0. Banana 3 units: 150
1. Orange 5 units: 250
As iandouglas wrote, you are overwriting the session variable every time. The following code also fixes some undefined index issues and already existing products.
// Test POST data.
$_POST['product'] = 'Pineaple';
$_POST['quantity'] = 1;
$_POST['code'] = 1;
//Getting the list
$_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$new_item = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
$new_product = true;
foreach($_SESSION['list'] as $key => $item) {
if ($item['item'] == $new_item['item']) {
$_SESSION['list'][$key]['quantity'] += $new_item['quantity'];
$_SESSION['list'][$key]['price'] = $products[$new_item['item']] * $new_item['quantity'];
$new_product = false;
}
}
if ($new_product) {
$_SESSION['list'][] = $new_item;
}
//listing
echo "<b>SHOPPIGN LIST</b></br>";
foreach($_SESSION['list'] as $key => $item) {
echo 'key '. $key. ' '. $item['item'], ' ', $item['quantity'], ' units: ', $item['price']. '<br />';
}