Here's the code:
if($condition == 'condition1' || $condition == 'condition2')
{
$found = false;
//loop through the array of customers contracts
foreach($cust_cont as $cust)
{
//if the customer is found
if ($cust["customer"] == $customer)
{
$temp = floatval($cust["hoursThisPer"]);
$temp += $time;
$cust["hoursThisPer"] = $temp;
$found = true;
}
}
if ($found == false)
{
$cust_cont[] = array("customer" => "$customer", "hoursUsed" => $hoursUsed,
"hoursAvail" => $allowed, "hoursThisPer" => (0 + $time));
}
}
So, what I'm trying to get this to do is traverse an array. If the array does have an entry for a customer, I want to add time to that customer's used time. If there is not an entry for the customer, I want to create an entry for that customer in my array and initialize it's values.
The array's entries are getting initialized properly, but when I try to update them, something funky is happening. For example, if I have customer1 in the array and I want to add to customer1's hoursThisPer, it goes through the motions of adding to that spot. However, the next time it needs to update, customer1's hoursThisPer is set to the initial value as opposed to the updated value. I can't figure out the flaw in my logic. Help would be greatly appreciated. I have some sample output.
Customer1:0.25
time: 0.25
temp: 0.5
0.5
Customer1:0.25
time: 1.50
temp: 1.75
1.75
Customer1:0.25
time: 0.50
temp: 0.75
0.75
The format is Customer: initial time; time to add; the expected total of initial time + added time; the array's value after being "updated"; the next instance of the customer being found (and the cycle continues).
You need to fetch your array by reference, otherwise you're just updating a new variable called $cust:
if($condition == 'condition1' || $condition == 'condition2')
{
$found = false;
//loop through the array of customers contracts
foreach($cust_cont as &$cust)
{
//if the customer is found
if ($cust["customer"] == $customer)
{
$temp = floatval($cust["hoursThisPer"]);
$temp += $time;
$cust["hoursThisPer"] = $temp;
$found = true;
}
}
if ($found == false)
{
$cust_cont[] = array("customer" => "$customer", "hoursUsed" => $hoursUsed,
"hoursAvail" => $allowed, "hoursThisPer" => (0 + $time));
}
}
Here I added a & before $cust declaration in the foreach loop. With this $cust is not a new variable with the value of the current $cust_cont element but an actual reference to this element.
By default the variables created inn foreach loops ($cust in this case) are created by value rather than by reference.
You could either change it to pass by reference (by prefixing with an &, as suggested by splash58 in a comment), allowing you to alter the original array by changing the created variable:
foreach($cust_cont as &$cust)
{
//if the customer is found
if ($cust["customer"] == $customer)
{
$temp = floatval($cust["hoursThisPer"]);
$temp += $time;
$cust["hoursThisPer"] = $temp;
$found = true;
}
}
or you could also get the relevant index and edit the array directly;
foreach($cust_cont as $index => $cust)
{
//if the customer is found
if ($cust["customer"] == $customer)
{
$temp = floatval($cust["hoursThisPer"]);
$temp += $time;
$cust_cont[$index]["hoursThisPer"] = $temp;
$found = true;
}
}
Personally I find it easy to miss the "&" so prefer the second option but I'm sure that's not even close to a universal opinion.
As PHP Manual says: http://php.net/manual/en/control-structures.foreach.php
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
Related
I have a button next to all my 'shop items' that can remove one of the shop item, however i need it to just remove one, and not rid the entire array of the number, i thought this was possible by using a break statement when i found the number i want to remove, but it removes all of the numbers.
if (isset($_GET['remove']) && isset($_SESSION['shopitems'])) {
if (in_array($_GET['remove'], $_SESSION['shopitems'])) {
for ($i = 0; $i < sizeof($_SESSION['shopitems']); $i++) {
if ($_SESSION['shopitems'][$i] == $_GET['remove']) {
$shopArray = $_SESSION['shopitems'];
if(sizeof($shopArray) == 1) {
$_SESSION['shopitems'] = null;
$_SESSION['added'] = null;
} else {
array_splice($shopArray, $i, $i);
$_SESSION['shopitems'] = $shopArray;
}
break;
}
}
}
}
Here i check if the URL contains the remove variable and the session is set, once i have done this, i check if the array contains the number that is put in the URL, if so i'll start a for loop and check if the key index of the session shop items is equal to the URL variable, if so i want to remove it, however if i use array_splice, suddenly they are all gone, is this because of the function i am using? Or is the break not executing correctly?
Why don't you try array_search() and unset()? It's easier, have a look at the code below and adapt it to your situation:
$array = [1, 5, 6, 12];
$wantToRemove = 5;
$key = array_search($wantToRemove, $array);
unset($array[$key]);
var_dump($array);
You can format your $_SESSION['shopitems'] like this :
$_SESSION['shopitems'] = array (
"item_id" => "item_info",
"item2_id" => "item2_info",
...
)
and do unset($_SESSION['shopitems'][$_GET['remove']]).
Your code could be :
if (isset($_GET['remove']) && isset($_SESSION['shopitems']))
if (isset($_SESSION['shopitems'][$_GET['remove']]))
unset($_SESSION['shopitems'][$_GET['remove']])
i need to define the array values as need. Here i say that the value will be 0 to 2. But i need someway to say the value can be null and also it can be 0 to 1000.
$apartment = array(
0,
1,
2
);
foreach ($apartment AS $apt) {
$userApt = $area->getApartments()->get($apt)->getApartment();
echo $userApt . "<br>";
}
Please note that the value can be 0 and it should stop where there is no available value ...
i mean if get(0) is available it should get the value, if get(1) is not available it should stop there and do nothing , so the main purpose is to get the value where it is available, when it is not available, do nothing...
According to your lasts edits, there is no need to build such an array. You can get your objects directly within the loop.
<?php
for($i = 0; $i <= 1000; ++$i) {
$userApt = $area->getApartments()->get($i);
if(!$userApt) {
break;
} else {
var_dump($userApt->getApartment());
}
}
This would stop as soon as an object cannot be retrieved.
I have this code for my school project and thought the code does its job on what i wanted it to do, i still keep on getting the error about $_SESSION[] is not an array argument when using the array_replace() and array_merge() functions:
Session is already initiated on the header:
// Start Session
session_start();
For initialising the $_SESSION['cart'] as an array:
// Parent array of all items, initialized if not already...
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
For adding products from a dropdown menu: - (Just to see how the session is assigned:)
if (isset($_POST['new_item'])) { // If user submitted a product
$name = $_POST['products']; // product value is set to $name
// Validate adding products:
if ($name == 'Select a product') { // Check if default - No product selected
$order_error = '<div class="center"><label class="error">Please select a product</label></div>';
} elseif (in_array_find($name, $_SESSION['cart']) == true) { // Check if product is already in cart:
$order_error = '<div class="center"><label class="error">This item has already been added!</label></div>';
} else {
// Put values into session:
// Default quantity = 1:
$_SESSION['cart'][$name] = array('quantity' => 1);
}
}
Then here is where the issue comes, when they try to update the product:
// for updating product quantity:
if(isset($_POST['update'])) {
// identify which product to update:
$to_update = $_POST['hidden'];
// check if product array exist:
if (in_array_find($to_update, $_SESSION['cart'])) {
// Replace/Update the values:
// ['cart'] is the session name
// ['$to_update'] is the name of the product
// [0] represesents quantity
$base = $_SESSION['cart'][$to_update]['quantity'] ;
$replacement = $_SESSION['cart'][$to_update] = array('quantity' => $_POST['option']);
array_replace($base, $replacement);
// Alternatively use array merge for php < 5.3
// array_merge($replacement, $base);
}
}
Note that both the functions array_replace() and array_merge() are updating the values and doing what the initial goal was, but the problem is that i still keep on getting that one argument($base) is not an array issue.
Warning: array_replace() [function.array-replace]: Argument #1 is not an array in ...
any suggestions for a better way to approach this issue would be a valuable help :)
Thanks for your help :)
Edit: The in_array_find() is a function that i use in replacement of in_array() as it doesn't apply to finding values in a multi-dimensional array: specifically 2 depth arrays:
found it from here and it works for me
The code for it is:
// Function for searching values inside a multi array:
function in_array_find($needle, $haystack, $strict = false) {
foreach ($haystack as $item => $arr) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
array_replace returns the replaced array. So you need to do:
$base=array_replace($base, $replacement);
Also, I suggest using named keys consistently throughout, as opposed to mixing named and numeric:
$base = $_SESSION['cart'][$to_update]['quantity'];
EDIT:
This may not be exactly what you're going for...
I set up a test situation without using $_SESSION, and I got the same error you did. I changed the code as follows and no longer get the error.
$sesh=array(
'cart'=>array(
0=>array(
'quantity'=>1
)
)
);
$to_update=0;
$new_quantity=5;
//$base = $sesh['cart'][$to_update]['quantity']; <--- changed this to line below
$base = $sesh['cart'][$to_update];
$replacement = $sesh['cart'][$to_update] = array('quantity' => $new_quantity);
$base=array_replace($base, $replacement);
echo"<pre>";print_r($base);echo"</pre>";
PHP FIDDLE: http://phpfiddle.org/main/code/mvr-shr
This have solved this issue:
Basically as per the structure: (Lets slice it into bits)
$_SESSION['cart'] = array();
then
$_SESSION['cart'][$name] = array('quantity' => 1);
finally:
$base = $_SESSION['cart'][$to_update]['quantity'] ;
$replacement = $_SESSION['cart'][$to_update] = array('quantity' => $_POST['option']);
array_replace($base, $replacement);
The reason why it says that the argument $base is not an array is because:
['quantity'] in $base is not an array as it forms the 'quantity' => 1 what we need is the array() value from the array('quantity' => 1); for it to be identified as an array.
So final answer should be: $base = $_SESSION['cart'][$to_update];
as there is only one array() recorded in where the $to_update resides so the replacement argument shall replace this identified array.
$_SESSION only exists when a Session starts. In order to do that you need to add on top of all your code session_start() otherwise the session will not start, unless you define it on php directives.
I'm pretty new to PHP and programming so I'm having troubles with this thing.
The purpose of the whole situation is to read a column from tab delimited file (already did that), get all different items in it, count them individually and put them in table with Column1[item value - label], Column2[count].
I have the whole column in 1 dimension array. Now, I want to list all the items there and their counts beside. The problem is, I could have more than 10 different items, even more, so I can't do it manually (name 10 variables and count each) like this:
$arr = array("complete","fail","complete","exit","fail","fail","complete");
function isComplete($value){
return ($value == "complete") ? true : false;
}
$complete = array_filter($array, 'isComplete');
<tr>
<td>Complete</td>
<td><?php echo count($complete)?></td>
</tr>
-- > Complete = 3
I want to avoid manually creating every function for each value because values can differ from file to file.
The number of items in $array can go up to 20+k so I need all automated. Can someone help me with this?
How about going through the array and placing the counts in another array? ($arrCount)
$arr = array("complete","fail","complete","exit","fail","fail","complete");
$arrCount = Array();
foreach($arr as $value){
$arrCount[$value] = array_key_exists($value,$arrCount) ? $arrCount[$value]+1 : 1;
//If this key exists, add 1 to it, else make it equal to 1
}
This would create an array with the keys being the various labels and the value equally to the label total.
print_r output:
Array ( [complete] => 3 [fail] => 3 [exit] => 1 )
Psuedo code:
$arr = array("complete","fail","complete","exit","fail","fail","complete");
$counts = array();
foreach($arr => $key as $value)
{
if(array_key_exists($value, $counts))
{
$counts[$value]++;
}else{
$counts[$value] = 1;
}
}
foreach($counts => $key as $value)
{
echo '<tr>
<td>' . $key . '</td>
<td>' . $value . '</td>
</tr>';
}
We are making arrays of the elements in the list. If the item exists, increase otherwise create with value 1. Than loop another time to show to the user the total count of each item.
Maybe I'm missing the point, but what is the problem with a normal loop?
For example:
function countByValue($array, $value){
$count = 0;
foreach($array as $val){
if ($val == $value){
$count++;
}
}
return $count;
}
And call it with
$complete = countByValue($arr, 'complete');
If you want to count them all at once go with F4r-20 answer.
$list = array(
[0]=> array(
[name]=>'James'
[group]=>''
)
[1]=> array(
[name]=>'Bobby'
[group]=>''
)
)
I am looking to update the item 'group' where the name is 'Bobby'. I am looking for a solution with the two following formats. Thank you in advance for your replies. Cheers. Marc.
array_push($list, ???)
and
$list[] ??? = someting
As far as I know, there's no way updating your array with one of the given syntax.
The only similar thing I can come on is looping over the array using array_walk ... http://www.php.net/manual/en/function.array-walk.php
Example:
array_walk($list, function($val, $key) use(&$list){
if ($val['name'] == 'Bobby') {
// If you'd use $val['group'] here you'd just editing a copy :)
$list[$key]['group'] = "someting";
}
});
EDIT: Example is using anonymous functions which is only possible since PHP 5.3. Documentation offers also ways working with older PHP-versions.
This code may help you:
$listSize = count($list);
for( $i = 0; $i < $listSize; ++$i ) {
if( $list[$i]['name'] == 'Bobby' ) {
$list[$i]['group'] = 'Hai';
}
}
array_push() doesn't really relate to updating a value, it only adds another value to an array.
You cannot have a solution that will fit both formats. The implicit array push $var[] is a syntactic construct, and you cannot invent new ones - certainly not in PHP, and not most (all?) other languages either.
Aside from that, what you are doing is not pushing an item on to the array. For one thing, pushing items implies an indexed array (yours is associative), and for another pushing implies adding a key to the array (the key you want to update already exists).
You can write a function to do it, something like this:
function array_update(&$array, $newData, $where = array(), $strict = FALSE) {
// Check input vars are arrays
if (!is_array($array) || !is_array($newData) || !is_array($where)) return FALSE;
$updated = 0;
foreach ($array as &$item) { // Loop main array
foreach ($where as $key => $val) { // Loop condition array and compare with current item
if (!isset($item[$key]) || (!$strict && $item[$key] != $val) || ($strict && $item[$key] !== $val)) {
continue 2; // if item is not a match, skip to the next one
}
}
// If we get this far, item should be updated
$item = array_merge($item, $newData);
$updated++;
}
return $updated;
}
// Usage
$newData = array(
'group' => '???'
);
$where = array(
'name' => 'Bobby'
);
array_update($list, $newData, $where);
// Input $array and $newData array are required, $where array can be omitted to
// update all items in $array. Supply TRUE to the forth argument to force strict
// typed comparisons when looking for item(s) to update. Multiple keys can be
// supplied in $where to match more than one condition.
// Returns the number of items in the input array that were modified, or FALSE on error.