I am trying to display the values from database to excel sheet, the problem is that I am having an undefined offset error
The problem starts here:
Code:
The enrollmentID is my key to identify each value, the foreach is the problem where the undefined offset is. Is there a way to fix this so I can display my data in excel?
if($key == 'enrollmentID'){
$intLec = 0;
$intLab = 0;
foreach ($enrollmentSubjectListData[$value]['subjectCode'] as $subjKey => $subjValue) {
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $subjValue);
$col++;
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $enrollmentSubjectListData[$value]['numericalEquivalent'][$subjKey]);
$col++;
if($enrollmentSubjectListData[$value]['lab'][$subjKey] != 0)
$units = $enrollmentSubjectListData[$value]['lec'][$subjKey] . '/' . $enrollmentSubjectListData[$value]['lab'][$subjKey];
else
$units = $enrollmentSubjectListData[$value]['lec'][$subjKey];
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $units);
$col++;
$intLec += (float)str_replace(array( '(', ')' ), '', $enrollmentSubjectListData[$value]['lec'][$subjKey]);
$intLab += (float)$enrollmentSubjectListData[$value]['lab'][$subjKey];
}
if($intLab == 0){
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $intLec);
}
else{
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $intLec . '/' . $intLab);
}
}
An undefined offset error generally means that the key you are trying to retrieve in your array does not exist.
Here, if the error is thrown in the foreach statement, the reason could either be that :
The $value key does not exist in the $enrollmentSubjectListData array
Or, that the $enrollmentSubjectListData[$value] does not contain a 'subjectCode' key (or simply that $enrollmentSubjectListData[$value] is not an array)
One simple fix that you could implement is to surround your foreach by an IF statement :
// Making sure that the $value key exists in the $enrollmentSubjectListData array
if(key_exists($value,$enrollmentSubjectListData))
{
$valueArray = $enrollmentSubjectListData[$value];
// Making sure that the $valueArray is an array and that the $valueArray['subjectCode'] key exists
if(is_array($valueArray) && (key_exists('subjectCode',$valueArray)))
{
$subjectCodeArray = $valueArray['subjectCode'];
// Making sure that the $subjectCodeArray is an array
if(is_array($subjectCodeArray))
{
foreach ($subjectCodeArray as $subjKey => $subjValue) {
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $subjValue);
$col++;
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $enrollmentSubjectListData[$value]['numericalEquivalent'][$subjKey]);
$col++;
if($enrollmentSubjectListData[$value]['lab'][$subjKey] != 0)
$units = $enrollmentSubjectListData[$value]['lec'][$subjKey] . '/' . $enrollmentSubjectListData[$value]['lab'][$subjKey];
else
$units = $enrollmentSubjectListData[$value]['lec'][$subjKey];
$coordinates = $this->getExcelColumnConversion($col) . $row;
$this->excel->getActiveSheet()->setCellValue($coordinates, $units);
$col++;
$intLec += (float)str_replace(array( '(', ')' ), '', $enrollmentSubjectListData[$value]['lec'][$subjKey]);
$intLab += (float)$enrollmentSubjectListData[$value]['lab'][$subjKey];
}
}
}
}
Just keep in mind that this snippet of code will only prevent your code from crashing but it will not tell you why your input data was not properly formatted in the first place.
For that, I will suggest you to use a debugger such as xDebug in your IDE.
Related
I have below loop:
$Sum = '';
$CommodityCode = '';
foreach ($obj['statisticalvalues'] as $key => $value) {
if (isset($obj['commoditycodes'][$key]['match'])) {
//If our commodity code from last iteration is the same as current = we have a duplicate!
if ($CommodityCode !== $obj['commoditycodes'][$key]['match']) {
$Sum = $value['key_0'];
} else {
$Sum += $value['key_0'];
}
$ReturnString .= '' . $obj['commoditycodes'][$key]['match'] . '';
$ReturnString .= '' . $Sum . '';
//Set the code for next iteration
$CommodityCode = $obj['commoditycodes'][$key]['match'];
}
}
Which will output:
CODE VALUE
3002190000 610.20
3002190000 846.7
3002190000 1083.2
3002190000 4156.4
3002190000 4461.5
3002190000 4711.4
3002190000 5061.4
3002190000 6061
3002190000 6886.3
3002190000 7136.2
3002190000 7435.8
3002190000 8196
3002190000 8466.2
8000120000 1000.5
As you can see, the VALUE are summing correctly, but it still prints out the CODE for each line.
I am trying to do, so it will only print out distinct values -- but still sum the total value for that code, like below:
CODE VALUE
3002190000 8466.2
8000120000 1000.5
Assuming the $input array has at least two columns per row, namely 'CODE' and 'VALUE', we can use the 'CODE' as a key (which is intrinsically unique) to sum the values in our $output array:
$output = array();
foreach($input as $row)
{
$key = $row['CODE'];
$value = $row['VALUE'];
$output[$key] = isset($output[$key]) ? $output[$key] + $value : $value;
}
print_r($output);
Please note that the above solution causes the $output array to grow dynamically, which can be a (time) problem for large arrays. If this is the case, please consider pre-calculating unique values for $input[$i]['CODE'] $i=1 ... count($input) so that you can pre-allocate the $output array by using array_pad.
Use php's array_unique if you want distinct values.
Keys are always distinct so you do not have to worry about that.
If you want to preserve your original array, create a new array with the following code.
<?php
$newArrayDistinct = array_unique($obj['statisticalvalues']);
foreach(newArrayDistinct as $key=>$value){
// your code here.
}
if you want to this with your current code, you can use this...
$Sum = '';
$CommodityCode = '';
$obj['statisticalvalues'] = array_unique($obj['statisticalvalues']);
foreach ($obj['statisticalvalues'] as $key => $value) {
if (isset($obj['commoditycodes'][$key]['match'])) {
//If our commodity code from last iteration is the same as current = we have a duplicate!
if ($CommodityCode !== $obj['commoditycodes'][$key]['match']) {
$Sum = $value['key_0'];
} else {
$Sum += $value['key_0'];
}
$ReturnString .= '' . $obj['commoditycodes'][$key]['match'] . '';
$ReturnString .= '' . $Sum . '';
//Set the code for next iteration
$CommodityCode = $obj['commoditycodes'][$key]['match'];
}
}
You only want to add the output when the value changes, which has two possible places. The first is when you detect that the code has changed (although you don't want to output it if this is the very first time) and the second is after the loop has finished (to clear up the last entry if there is one)...
$Sum = '';
$CommodityCode = '';
foreach ($obj['statisticalvalues'] as $key => $value) {
if (isset($obj['commoditycodes'][$key]['match'])) {
//If our commodity code from last iteration is the same as current = we have a duplicate!
if ($CommodityCode !== $obj['commoditycodes'][$key]['match']) {
if ( $CommodityCode != '' ) {
$ReturnString .= '' . $obj['commoditycodes'][$key]['match'] . '';
$ReturnString .= '' . $Sum . '';
}
$Sum = $value['key_0'];
} else {
$Sum += $value['key_0'];
}
//Set the code for next iteration
$CommodityCode = $obj['commoditycodes'][$key]['match'];
}
}
if ( $CommodityCode != '' ) {
$ReturnString .= '' . $obj['commoditycodes'][$key]['match'] . '';
$ReturnString .= '' . $Sum . '';
}
(I have no data so can't test this, but hopefully it should be OK)
here is an example that maybe related to your problem
$input = array(
array('code'=>'ID001', 'value'=>100),
array('code'=>'ID001', 'value'=>78),
array('code'=>'ID002', 'value'=>123),
array('code'=>'ID002', 'value'=>104),
array('code'=>'ID001', 'value'=>119),
array('code'=>'ID001', 'value'=>93),
array('code'=>'ID003', 'value'=>55),
);
//process
$output=array();
foreach($input as $item){
if(isset($output[$item['code']])){
$output[$item['code']] += $item['value'];
}else{
$output[$item['code']] = $item['value'];
}
}
//print output
echo "CODE : VALUE";
foreach($output as $code=>$value){
echo "<br>$code : $value";
}
I am trying to create an associate array like this
while($row = $result1->fetch_assoc()) {
$user = $row['first_name'] ."_" . $row['last_name'];
$userholder[$user] = $row['choice'];
$event = $row['event_name'] . "_" . $row['event_location'] . "_" . $row['even_date'];
$consolidateEvents[$event] = $userholder;
}
but my $consolidateEvents array is numeric. I cannot see what I am doing wrong. Why am I not getting $event as the key for my array?
Try this code to correct your output,
function custom_function($input_array){
$output_array = array();
foreach ($input_array as $key => $value) {
foreach ($v as $k => $v) {
$output_array[$key][$k] = $v;
}
}
return $output_array;
}
Give it a try, this will work
I have a multi-dimension array in php like this
$shop = array(
array("name","point","number"),
array('Ranjit', 1.25 , 15),
array('Pitabas', 0.75 , 25),
array('Khela', 1.15 , 7)
);
Now I have to show the output like this
name-> ranjit
Point-> 1.25
number->15
name->Pitabas
Point->0.75
number->25
name->Khela
Point->1.15
number->7
I am trying for loop, but I could get the result in nested forloop. Please help me to get the answer.
My solution:
$headings = array_shift($shop);
foreach ($shop as $item) {
foreach ($item as $key => $value) {
echo $headings[$key], '=>', $value;
}
}
Here's a simple loop: Observe that we skip the first element of the outer array, which is deemed to contain the headers:
for ($i = 1; $i != count($shop); ++$i)
{
print $shop[0][0] . ": ". $shop[$i][0] . "\n";
print $shop[0][1] . ": ". $shop[$i][1] . "\n";
print $shop[0][2] . ": ". $shop[$i][2] . "\n";
}
You know the first row will be the titles, so store them separately:
$titles = $shop[0];
That will give you
$titles = array('name', 'point', 'number');
Then loop through your array:
foreach ($shop as $index => $row) {
if ($index == 0)
continue;
foreach($row as $column => $item) {
echo $titles[$column] . " -> " . $item . "<br />";
}
}
This should give the desired output:
for($x = 1, $lim = sizeof($shop); $x < $lim; $x++)
{
echo $shop[0][0]."->".$shop[$x][0]."<br>";
echo $shop[0][1]."->".$shop[$x][1]."<br>";
echo $shop[0][2]."->".$shop[$x][2]."<br>";
}
PDO sql codes :
while($r = $q->fetch(PDO::FETCH_ASSOC)){
$gg = join('</td><td>', $r);
echo "<tr><td>" . $no_count . "</td><td>" . $gg . "</td></tr>";
$no_count = $no_count + 1;
}
variable $r is the record, how can I echo the field name of $r?
Let's say $r carry records from 2 different fields "product" and "price". The value of $r is "apple", "130". How can I add "usd" into "130"?
I need something like.... if $field_name == "$r['price']" { $r = join('usd', $r); };
Thanks to Mike B, I almost there :
while($r = $q->fetch(PDO::FETCH_ASSOC)){
foreach ($r as $name => $value) {
if ($name == "price"){
$r = "usd" . $value; // this line got problem, how to change the value in an array variable $r?
}
}
$gg = join('</td><td>', $r);
echo "<tr><td>" . $no_count . "</td><td>" . $gg . "</td></tr>";
$no_count = $no_count + 1;
}
array_keys($r) will get you a list of fields from the table since you're fetching an associative array.
You can also loop through $r:
foreach ($r as $name => $value) {
print "$name: " . $value;
}
Update
// this line got problem, how to change the value in an array variable $r?
$r[$name] = 'usd' . $value;
Make the edit to the original name. Since you have the key in the $name variable from the foreach loop you can set it directly.
I am trying to determine the end of a foreach loop that is seeded with a collection of DOMNodeList. Currently, I am using a for loop would like to avoid having a 'magic' number there. I do know there are only going to be 8 columns, but I would like the code me generic for other applications.
Is it possible to convert this to a Foreach loop? I have tried the end() and next() functions, but they are not returning any data and I suspect that they only work on arrays and not this DOMNodeList collection.
The code is building a CSV file without the trailing ','
Current output is:
"Value 1","Value 2","Value 3","Value 4","Value 5","Value 6","Value 7","Value 8"
Here is an example of code:
$cols = $row->getElementsByTagName("td");
$printData = true;
// Throw away the header row
if ($isFirst && $printData) {
$isFirst = false;
continue;
}
for ($i = 0; $i <= 8; $i++) {
$output = iconv("UTF-8", "ASCII//IGNORE", $cols->item($i)->nodeValue);
$output2 = trim($output);
if ($i == 8) {
// Last Column
echo "\"" . $output2 . "\"" . "\n";
} else {
echo "\"" . $output2 . "\"" . ",";
}
}
You can use:
$cols->length
To retrieve the number of items in a DOMNodeList.
See http://php.net/manual/en/class.domnodelist.php
Edit:
If you change you're code to this, you don't have to worry about the trailing comma, or the length:
$output = array();
foreach ($cols as $item) {
$output = iconv("UTF-8", "ASCII//IGNORE", $item->nodeValue);
$output2 = trim($output);
$output[] = '"' . $output2 . '"';
}
$outputstring = implode(',', $output);
$cols->length
Should give you the number of items in the list
for ($i = 0; $i < $cols->length; $i++) {
// ...
if ($i == $cols->length - 1) {
// last column