Can someone help me debug this error: Undefined offset: 0? - php

I am creating a function that calculate the quantity of sold tickets, and here is my code:
public function get_quantity($tickets_info){
$i = 0; //$i is the starting point of the loop
$k = 0;
$Qty = 1; // this is used to save the quantity of tickets, by default there is always one ticket
$index = array();
$quantity = array();
for($j = 1; $j < count($tickets_info); $j++) {
// if the ticket_id are the same, then increase the quantity by one
if($tickets_info[$i]['ticket_id'] == $tickets_info[$j]['ticket_id'])
{
$Qty++;
}
// if the ticket_id are not the same, then push the quantity into an array and remember the index
else
{
$idx = $j;//remember the index of the next first different ticket_id
$i = $j;//find the next starting point
$index[$k] = $idx;//push back the index of the next different ticket_id
$quantity[$k] = $Qty;//save quantity into the array
$k++;//increase the index poniter
$Qty = 1;//reset quantity back to one
}
}
// push the last quantity into the array
$quantity[$k+1] = $Qty;
//assign the ticket information into a new array
for($m = 0; $m < count($quantity); $m++){
$ticket[$m] = $tickets_info[$m];
}
//create the finally array, combine ticket information with quantity
$n = 0;
foreach($ticket as $row)
{
$row['Qty'] = $quantity[$n++];
}
return $ticket;
}
$ticket_info is a 2-D array which is generated from a SQL, and it has a structure like this:
$ticket_info
(
[0]=>array
(
[ticket_id] => 0001
[purchase_time] => 2014/01/02
....
)
[1]=>array
(
[ticket_id] => 0001
[purchase_time] => 2014/01/02
....
)
[2]=>array
(
[ticket_id] => 0001
[purchase_time] => 2014/01/02
....
)
....
)
Basically, if the tickets have the same ticket_id that means they have been bought at the same time (but in the database, I recorded them separately for a specific purpose), so I need to add them up and get the quantity.
I'm not familiar with PHP arrays, so I write my algorithm in C++ and tested it. It works fine. However, when I tried to write the real code in PHP, I got 2 errors:
For line, $ticket[$m] = $tickets_info[$m]; Message: Undefined offset: 0
For line, $row['Qty'] = $quantity[$n++]; Message: Undefined offset: 0
I don't know why there is no index 0, maybe I didn't initialize the array correctly or I didn't pass the data in $ticket_info in the right format? Can someone help me look at this code?

Do a check before you try access that index:
if (!empty($ticket) && !empty($tickets_info)) {
$ticket[$m] = $tickets_info[$m];
}

Related

Create a temporary array in PHP to add to a larger array

I am trying to create a number of arrays to add to a larger array which I will then index two dimensionally (for example my_array[i][j]).
I believe I am having some type of pointing issue... I am iterating through a loop.... at the top of each iteration I instantiate a new array with the same name. When I try and view the output each item in the array appears blank.
Is there a better way for me to instantiate the "temp" arrays to fill the larger (outer) array? Really appreciate any and all help, this community has helped me through so many questions :D
$main_array = array();
for($i = 0; $i < $member_count; $i++)
{
$temp_array = array();
//preform SQL query here
$sql_get_member_transactions = 'some SQL query to go to my DB';
foreach($sql_get_member_transactions as $row)
{
//cannot get array to update here
array_push($temp_array, $row['amount']);
}
array_push($main_array, $temp_array);
}
#***FULL CODE BELOW***
$club_transactions = array();
for($i = 0; $i < $member_count; $i++)
{
#create an array for each member in the club,
#add each memeber's array to a larger array once filled with deposit amounts
#here check if member had a deposit (later we will check ALL transaction types...)
#if no deposit on that date add a zero to their array
$temp_member_transactions = array();
$temp_member = my_members[$i];
$sql_member_transactions = "SELECT * FROM Transactions WHERE Date >= '$first_t_date' AND Date <= '$last_t_date' AND RelatedClubID = 'THH'";
$sql_get_member_transactions = mysqli_query($conn, $sql_member_transactions);
//here we will get all transactions that lie within the
//event-transaction-date-window... in otherwords, the date window
//in the year where members transactions occured
foreach($sql_get_member_transactions as $row)
{
//we only want to include the transaction amount
//in the member-specific array if it belongs to that member
//otherwise see "else"
if($row['T_Owner'] == $temp_member)
{
$z = $row['T_Amount'];
}
else
{
//set to 0 so that we still account for the transaction date
$z = 0;
}
array_push($temp_member_transactions, $z);
}
array_push($club_transactions, $temp_member_transactions );

submit form repeater values as array and loop through each

I have a form repeater like this
form repeater image
which submits a code(should be same all through) a product name and a quantity in thousands. eg
code-1234 product-book Qty - 5000
code-1234 product-pen Qty -3000
code-1234 product-ruler Qty -2000
what i would like is to submit to db all the above data as a json with an incrementing id as per total number of items in this case 10,000 and the product name beside each id. The product name should end where its specific quantity end e.g when the ids reach 5000 the next id should be 5001 and the name to begin showing pen.
I have tried this `
//array submited from form
$array = $request->get('arrayName');
foreach ($array as $key => $value) {
$items[] = $value['no_of_items'];
$a_sum = array_sum($items);
$length = 15;
$string = bin2hex(openssl_random_pseudo_bytes($length));
$maxNumberOfItems = $a_sum;
for ($a = 0; $a <= $maxNumberOfItems; $a++) {
if ($a <= reset($items) && $a === $maxNumberOfItems) {
$a = reset($items);
}
echo +$a . " => " . $value['item'] . "<br> ";
$temp = bin2hex(openssl_random_pseudo_bytes($length));
$coupons[] = [
'id' => +$a,
'item' => $value['item'],
'code' => $temp,
'item_status' => 'in-store',
];
}`
It display the names correctly but does not auto increment id as explained above. The moment it reaches say 5000 the next item starts at 0 instead of 5001. Any help would be highly appreciated.
You may need to manually get the MAX(id) and do:
for ($a = $maxId; $a <= $maxNumberOfItems + $maxId; $a++)

Recursive Array Cleanup

I have a function called combined which is going to loop through an array of orders. It is specifically searching for someone who placed more than 1 order and matches based on the customer's name and address line 1. If the customer places 2 orders this will catch them and combine them however if they have 3 or more if only catches 2. When I recursively call the function I get an invalid offset error which I do not understand as I thought the array index would refresh on every function call?
function combined(Array $all) {
//find any matching single orders and combine
$count = count($all);
$combinedorder = array();
for($i=1; $i < $count; $i++) {
for($j=1; $j < $count; $j++) {
//if order # is not the same
if(strcasecmp($all[$i][0], $all[$j][0]) !== 0){
//if name matches
if(strcasecmp($all[$i][2], $all[$j][2]) == 0) {
//if address line 1 matches
if(strcasecmp($all[$i][3], $all[$j][3]) == 0) {
$combinedorder[] = array('ordernos' => array($all[$i][0], $all[$j][0]), $all[$i][1], $all[$i][2], $all[$i][3], $all[$i][4], $all[$i][5], $all[$i][6], $all[$i][7], $all[$i][8], $all[$i][9], $all[$i][10], 'orders' => array($all[$i][11], $all[$j][11]));
unset($all[$i]);
unset($all[$j]);
$all = array_merge($all, $combinedorder);
$all = array_values($all);
reset($all);
//this recursive call does not work. undefined offset error
combined($all);
}
}
}
}
}
return $all;
}
You need to re-index the array. You are deleting some of the indexes with unset($all[$i]) and unset($all[$j]). So when the function calls itself and your loop hits the index that you deleted you get the invalid offset error.
To fix it just add this code after you unset some of the indexes to reset the keys of the array.
$all = array_values($all);

Fill Values in multidimensional Array (PHP)

I've got a small problem. I'm working on a little package/product-list.
If you're watching a Package, my website should show you which products are in there.
If a product is more than one time in it, the array should be deleted and the value of the leftover array should be + 1 (each deleted array).
So here's my code:
// $products_in_package has all products in it
// First of all, the products come from a db and don't have a count
// So i first give them a count of 1
foreach ($products_in_package as $product => $value) {
$products_in_package[$product]['count'] = intval(1);
}
foreach ($products_in_package as $product) {
$id_to_find = intval($product['ID']);
$product_count = intval($product['count']);
$found_id = 0;
// Now I try to find any ident products
// If found and over 1 time (beacouse he finds the first too of course)
// Then delete this array and count up the products count
for ($i=0; $i <= count($products_in_package); $i++) {
if(intval($products_in_package[$i]['ID']) === $id_to_find){
$found_id++;
if($found_id > 1){
$product_count = $product_count + 1;
$product['count'] = $product_count;
unset($products_in_package[$i]);
array_merge($products_in_package);
while($i > $products_in_package){
$i = 0;
}
}
}
}
}
What I'm getting is the correct multidimensional array but the count is still 1.
What's wrong with the code?
Everytime I try to log the code i'm getting the right integer. (No, I already tried to delete the chache)
But if I log the array out of the loops, I get always the count of 1.
$product is a copy of the array element, so when you do $product['count'] = $product_count you're assigning to a copy, not the original array.
You can fix this by using a reference in the foreach:
foreach ($products_in_package as &$product) {

Saving multiple HTML textareas in CodeIgniter

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);

Categories