Search code examples
phpapacherrdtool

PHP output to img tag


I have this script that outputs the image to command line and if I redirect it to a file.png I can see correctly the graph, but if I try to do the same from the browser I can't see it on the fly.

I tried to split the script in 2 parts too, but don't work.

1 -> Generate the graph 2 -> Call the first script from this one and save all in a variable.

The script:

<?php

header("Content-Type: image/png");
header("Content-Transfer-Encoding: binary");
ob_flush();

require_once ('/opt/rMON/config.php');

//if(isset($_GET['id'])){
//  $id = trim($_GET['id']);
//} else {
//  die("El id?");
//}
//DEBUG ID
$id=1;

$result = ***MYSQL QUERY***
$ip         = long2ip($result['ip']);
$interface  = $result['interface'];
$counter    = $result['counter'];
$unix_name  = $result['unix_name'];
$community  = $result['community'];
$version    = $result['version'];
$port       = $result['port'];
$rrd_file   = __RRD_ROOT__.$unix_name.".rrd";
$graph_name = $result['name'];
$host_ip    = long2ip($result['ip']);
$iface_name = $result['iface_name'];
$fecha      = date("y-m-d h:i:s");

$start = "3600";
$tiempo = "1 Hora";
create_graph($start, $graph_name, $fecha, $rrd_file, $input, $output, $host_ip, $iface_name, $tiempo);

function create_graph($start, $graph_name, $fecha, $rrd_file, $input, $output, $host_ip, $iface_name, $tiempo){
    $opts = array (
        "--imgformat=PNG",
        "--slope-mode",
        "--title=$graph_name ($host_ip) - $iface_name - $tiempo",
        "--rigid",
        "--base=1000",
        "--height=120",
        "--width=500",
        "--alt-autoscale-max",
        "--lower-limit=0",
        "--font=TITLE:10:",
        "--font=AXIS:8:",
        "--font=LEGEND:8:",
        "--font=UNIT:8:30:",
        "--watermark=$fecha - Radu Radu",
        "--start=-$start",
        "--end=now",
        "DEF:a=$rrd_file:$input:AVERAGE",
        "DEF:b=$rrd_file:$output:AVERAGE",
        "CDEF:cdefa=a,8,*",
        "CDEF:cdefe=b,8,*",
        "AREA:cdefa#00CF00FF:Entrante\t",
        "GPRINT:cdefa:LAST:Actual\:%8.2lf %s",
        "GPRINT:cdefa:AVERAGE:Promedio\:%8.2lf %s",
        "GPRINT:cdefa:MAX:Máximo\:%8.2lf %s",
        "LINE1:cdefe#002A97FF:Saliente\t",
        "GPRINT:cdefe:LAST:Actual\:%8.2lf %s",
        "GPRINT:cdefe:AVERAGE:Promedio\:%8.2lf %s",
        "GPRINT:cdefe:MAX:Máximo\:%8.2lf %s"
    );

    $ret = rrd_graph("-", $opts);
    if(!$ret){
        echo "ERROR en el objeto: $graph_name ".rrd_error()."\n";
    }
}
?>

I tried to output to php://output too with no luck.

As I see in the log, the output is going to the apache server log.

"dic 21 10:58:00 xxx.xxx.com httpd[27941]: [305B blob data]"

Thanks!!


Solution

  • You are doing it wrong. rrd_graph does not accept - for $filename and it returns an array with information about generated image; it does not output or flush any image data. The - $filename parameter is for the RRDGraph class. In order to have the image data, you need to either open the file generated by rrd_graph, read its data and output the data, or use RRDGraph returned array ['image'] key to get the binary image data.

    Using rrd_graph function

    function create_graph($start, $graph_name, $fecha, $rrd_file, $input, $output, $host_ip, $iface_name, $tiempo) {
        $opts = array (
            "--imgformat=PNG",
            "--slope-mode",
            "--title=$graph_name ($host_ip) - $iface_name - $tiempo",
            "--rigid",
            "--base=1000",
            "--height=120",
            "--width=500",
            "--alt-autoscale-max",
            "--lower-limit=0",
            "--font=TITLE:10:",
            "--font=AXIS:8:",
            "--font=LEGEND:8:",
            "--font=UNIT:8:30:",
            "--watermark=$fecha - Radu Radu",
            "--start=-$start",
            "--end=now",
            "DEF:a=$rrd_file:$input:AVERAGE",
            "DEF:b=$rrd_file:$output:AVERAGE",
            "CDEF:cdefa=a,8,*",
            "CDEF:cdefe=b,8,*",
            "AREA:cdefa#00CF00FF:Entrante\t",
            "GPRINT:cdefa:LAST:Actual\:%8.2lf %s",
            "GPRINT:cdefa:AVERAGE:Promedio\:%8.2lf %s",
            "GPRINT:cdefa:MAX:Máximo\:%8.2lf %s",
            "LINE1:cdefe#002A97FF:Saliente\t",
            "GPRINT:cdefe:LAST:Actual\:%8.2lf %s",
            "GPRINT:cdefe:AVERAGE:Promedio\:%8.2lf %s",
            "GPRINT:cdefe:MAX:Máximo\:%8.2lf %s"
        );
    
        $fileName = "rrd.png";
        $ret = rrd_graph($fileName, $opts);
    
        if(!$ret){
            echo "ERROR en el objeto: $graph_name ".rrd_error()."\n";
        }
        else {
            header("Content-Type: image/png");
            header("Content-Length: " . filesize($fileName));
            $fp = fopen($fileName, 'rb');
            if($fp) {
                fpassthru($fp);
                fclose($fp);
                exit();
            }
        }
    }
    

    Using RRDGraph class

    function create_graph($start, $graph_name, $fecha, $rrd_file, $input, $output, $host_ip, $iface_name, $tiempo){
        $opts = array (
            "--imgformat=PNG",
            "--slope-mode",
            "--title=$graph_name ($host_ip) - $iface_name - $tiempo",
            "--rigid",
            "--base=1000",
            "--height=120",
            "--width=500",
            "--alt-autoscale-max",
            "--lower-limit=0",
            "--font=TITLE:10:",
            "--font=AXIS:8:",
            "--font=LEGEND:8:",
            "--font=UNIT:8:30:",
            "--watermark=$fecha - Radu Radu",
            "--start=-$start",
            "--end=now",
            "DEF:a=$rrd_file:$input:AVERAGE",
            "DEF:b=$rrd_file:$output:AVERAGE",
            "CDEF:cdefa=a,8,*",
            "CDEF:cdefe=b,8,*",
            "AREA:cdefa#00CF00FF:Entrante\t",
            "GPRINT:cdefa:LAST:Actual\:%8.2lf %s",
            "GPRINT:cdefa:AVERAGE:Promedio\:%8.2lf %s",
            "GPRINT:cdefa:MAX:Máximo\:%8.2lf %s",
            "LINE1:cdefe#002A97FF:Saliente\t",
            "GPRINT:cdefe:LAST:Actual\:%8.2lf %s",
            "GPRINT:cdefe:AVERAGE:Promedio\:%8.2lf %s",
            "GPRINT:cdefe:MAX:Máximo\:%8.2lf %s"
        );
    
        $graphObj = new RRDGraph('-');
        $graphObj->setOptions($opts);
        $ret = $graphObj->saveVerbose();
    
        if(!$ret){
            echo "ERROR en el objeto: $graph_name ".rrd_error()."\n";
        }
        else {
            header("Content-type: image/png");
            echo $res['image'];
            exit();
        }
    }
    

    You can read the question and answers here for a problem similar to yours.