0

I have a login page where a user selects one of the options. Then it has to display a graph. But I get this error

Cannot modify header information - headers already sent by (output started at /var/www/databin/php/visual/chart.php:136) in /var/www/databin/php/visual/chart.php on line 126

I tried a lot to understand from forums, but I could not.

Thanks for any help.

Here is the code

<?php
function subval_sort($a,$subkey) {
 foreach($a as $k=>$v) {
  $b[$k] = strtolower($v[$subkey]);
 }
 asort($b);
 foreach($b as $key=>$val) {
  $c[] = $a[$key];
 }
 return $c;
}

function display_graph($str)
{
echo $str;
$data = array( 
"Jan" => 55, 
"Feb" => 54, 
"Mar" => 53, 
"Apr" => 33, 
"May" => 13, 
"Jun" => 15, 
"Jul" => 23, 
"Aug" => 28, 
"Sep" => 32, 
"Oct" => 45, 
"Nov" => 73, 
"Dec" => 71); 

// create image 
$width = 480; 
$height = 250; 
$image = imagecreate($width, $height); 

// colors 
$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); 
$navy = imagecolorallocate($image, 0x00, 0x00, 0x80); 
$black = imagecolorallocate($image, 0x00, 0x00, 0x00); 
$gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0); 

// layout 
$maxval = max($data); 
$nval = sizeof($data); 

$vmargin = 20; // top (bottom) vertical margin for title (x-labels) 
$hmargin = 38; // left horizontal margin for y-labels 

$base = floor(($width - $hmargin) / $nval); // distance between columns 

$ysize = $height - 2 * $vmargin; // y-size of plot 
$xsize = $nval * $base; // x-size of plot 

// title 
$titlefont = 3; 
$title = "Presidential Approval Ratings 2000 (in %)"; 

$txtsz = imagefontwidth($titlefont) * strlen($title); // pixel-width of title 

$xpos = (int)($hmargin + ($xsize - $txtsz)/2); // center the title 
$xpos = max(1, $xpos); // force positive coordinates 
$ypos = 3; // distance from top 

imagestring($image, $titlefont, $xpos, $ypos, $title , $black); 

// y labels and grid lines 
$labelfont = 2; 
$ngrid = 4; // number of grid lines 

$dydat = $maxval / $ngrid; // data units between grid lines 
$dypix = $ysize / ($ngrid + 1); // pixels between grid lines 

for ($i = 0; $i <= ($ngrid + 1); $i++) { 
    // iterate over y ticks 

    // height of grid line in units of data 
    $ydat = (int)($i * $dydat); 

    // height of grid line in pixels
    $ypos = $vmargin + $ysize - (int)($i*$dypix); 

    $txtsz = imagefontwidth($labelfont) * strlen($ydat); // pixel-width of label 
    $txtht = imagefontheight($labelfont); // pixel-height of label 

    $xpos = (int)(($hmargin - $txtsz) / 2); 
    $xpos = max(1, $xpos); 

    imagestring($image, $labelfont, $xpos, 
        $ypos - (int)($txtht/2), $ydat, $black); 

    if (!($i == 0) && !($i > $ngrid)) {
        imageline($image, $hmargin - 3, 
            $ypos, $hmargin + $xsize, $ypos, $gray); 
        // don't draw at Y=0 and top 
    }
} 

// columns and x labels 
$padding = 3; // half of spacing between columns 
$yscale = $ysize / (($ngrid+1) * $dydat); // pixels per data unit 

for ($i = 0; list($xval, $yval) = each($data); $i++) { 

    // vertical columns 
    $ymax = $vmargin + $ysize; 
    $ymin = $ymax - (int)($yval*$yscale); 
    $xmax = $hmargin + ($i+1)*$base - $padding; 
    $xmin = $hmargin + $i*$base + $padding; 

    imagefilledrectangle($image, $xmin, $ymin, $xmax, $ymax, $navy); 

    // x labels 
    $txtsz = imagefontwidth($labelfont) * strlen($xval); 

    $xpos = $xmin + (int)(($base - $txtsz) / 2); 
    $xpos = max($xmin, $xpos); 
    $ypos = $ymax + 3; // distance from x axis 

    imagestring($image, $labelfont, $xpos, $ypos, $xval, $black); 
} 

// plot frame 
imagerectangle($image, $hmargin, $vmargin, 
    $hmargin + $xsize, $vmargin + $ysize, $black); 

// flush image 
header("Content-type: image/gif"); // or "Content-type: image/png" 
imagegif($image); // or imagepng($image) 
imagedestroy($image); 
}
?>

<html>
<body>
<form method="GET"  action="">
<input type="submit" name="name" value="Submit">
<?php

    echo "<select name=\"name\">";
    echo "<option size =30 selected>Select</option>";

 $initDir = "/var/www/databin/userfiles/";
  $peoplearr = scandir ($initDir);

foreach ($peoplearr as $person)
  {
    if (strcmp ($person, ".") == 0)
      continue;
    if (strcmp ($person, "..") == 0)
      continue;
    $str = str_replace(".html","",$person);

    echo "<option>$str</option>";

  }
echo "</select>";
if(isset($_GET['name']))
{
echo $_GET['name'];
$user = $_GET['name'];
$initdir = "/var/www/databin/userfiles/";
$person = $user.".html/";
$person_comparisons = array();
$display_arr       = array();
$str = file_get_contents($initdir.$person."person_comparison");
$person_comparisons = json_decode($str,true);
$i = 0;
if($person_comparisons[$i])
{
while(true)
 {
 $display_arr[$i]['name'] = $person_comparisons[$i]['name'];
 $display_arr[$i]['sim'] = $person_comparisons[$i]['sim'];
 $i = $i + 1;
 if(!$person_comparisons[$i]) break;
 }

$display_arr = subval_sort($display_arr,'sim'); 
print_r($display_arr);
display_graph($display_arr);
}// end if

}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
doni
  • 1

2 Answers2

1

Typical error. display_graph() function calls:

header("Content-type: image/gif"); // or "Content-type: image/png"

which should be very first thing to output.

In your case you are generating both html content and png image on the same page, which is wrong. Move png part to a separate file, i.e. display_graph.php, and call it like this from your html code:

<img src="display_graph.php?param1=1&param2=2"/>
Andrejs Cainikovs
  • 27,428
  • 2
  • 75
  • 95
0

You are printing headers after some other output print and that is wrong, that's why it complains. To fix it you have to be sure that there is no output before any call of the

header()

Sometimes it can also depend on whitespaces before tags so be sure that you have nothing before the first

If it is not the easy case check that there are not print / echo before any header call

EDIT:

Ok, It's not the whitespace case for sure!

Probably the best is to move the image creation in a different php script like graph_image.php then in the spot where you want the graph to do something like

<img src="graph_image.php?name=<?php print $_GET['name'];" />

You do this by moving all the code in the top and most of the code where you create the array or whatever you send as argument to the function that then creates the image.

Tommaso Barbugli
  • 11,781
  • 2
  • 42
  • 41