Изображение в реальном времени из файла rrd в PHP

Я хотел бы создать изображение «в реальном времени» из файла rrd в сценарии php, но безуспешно. Это php-скрипт (/var/www/rrd_image.php), который должен сгенерировать картинку:

<?php
  header("Content-type: image/png");

  $options = array(
    "--start", "-1d",
    "--title=xxx",
    "--lower-limit=0",
    "--width=450",
    "--height=120",
    "DEF:snr=/var/www/rrd/cm_100.rrd:snr:LAST",
    "CDEF:tsnr=snr,10,/",
    "LINE:tsnr#00FF00:US SNR",
    "GPRINT:tsnr:MIN:Min\: %3.1lf dB",
    "GPRINT:tsnr:MAX:Max\: %3.1lf dB",
    "GPRINT:tsnr:LAST:Pill\: %3.1lf dB",
  );

  rrd_graph("-", $options);
?>

Поэтому я называю это так:

<img src="rrd_image.php" />

Но картинка не завершена, в браузере вижу, что 0 байт, а в логе апача ошибки нет. (И когда я запускаю rrd_image.php из консоли, он работает, «изображение» отправляется на стандартный вывод.)


person dbndhjefj    schedule 05.12.2013    source источник
comment
Удалите header() и посмотрите, появится ли сообщение об ошибке.   -  person Pekka    schedule 05.12.2013
comment
Имеет ли пользователь вашего веб-сервера (например, apache) доступ для чтения к файлу rrd?   -  person l-x    schedule 05.12.2013
comment
Когда я удаляю заголовок (), сообщения об ошибке нет. Да, apache прочитал файл rrd, но странно: когда я удаляю этот файл rrd, в apache error.log также нет ошибки.   -  person dbndhjefj    schedule 05.12.2013
comment
Кажется, у вас есть файл php в вашем теге ‹img›, не уверен, что это должно работать...   -  person user2196728    schedule 05.12.2013
comment
php.net/manual/en/function.rrd-graph.php говорит нам и вам, что вы неправильно используете rrd_graph. Всегда проверяйте правильность использования функций.   -  person Mike 'Pomax' Kamermans    schedule 05.12.2013


Ответы (2)


Вы делаете это неправильно, потому что rrd_graph() возвращает array не изображение. Вы должны изменить это, чтобы оно выглядело так:

$fileName = "rrd.png";
rrd_graph($fileName, $options);

header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

$fp = fopen($name, 'rb');
if( $fp ) {
  fpassthru($fp);
  fclose($fp);
}

exit();

Всегда сначала читайте документацию: http://php.net/manual/en/function.rrd-graph.php

PS: Если вы не знаете, что вам это нужно, никогда не используйте ?> - это убережет вас от случайного вывода чего-либо обратно, например, в браузер (например, пробелы или LF после ?>)

person Marcin Orlowski    schedule 05.12.2013
comment
спасибо, но как я могу выполнить эту задачу без временного файла (rrd.png)? Можно ли сгенерировать изображение только в память, а не в обычный файл? - person dbndhjefj; 05.12.2013
comment
На данный момент не повезло, так как rrd_graph() вывод не может быть перенаправлен. Но вы можете уменьшить влияние, кэшируя выходной файл, а не создавая его для каждого запроса (поэтому, если ваше разрешение данных составляет, например, 5 минут, вы можете легко повторно использовать старое изображение, если оно не старше 5 минут. - person Marcin Orlowski; 06.12.2013

Возможность использования '-' в качестве имени файла существует в классе RRDGraph:

<?php
  $options = array(
    "--start", "-1d",
    "--title=xxx",
    "--lower-limit=0",
    "--width=450",
    "--height=120",
    "DEF:snr=/var/www/rrd/cm_100.rrd:snr:LAST",
    "CDEF:tsnr=snr,10,/",
    "LINE:tsnr#00FF00:US SNR",
    "GPRINT:tsnr:MIN:Min\: %3.1lf dB",
    "GPRINT:tsnr:MAX:Max\: %3.1lf dB",
    "GPRINT:tsnr:LAST:Pill\: %3.1lf dB",
  );

  $graphObj = new RRDGraph('-');
  $graphObj->setOptions($options);
  $res = $graphObj->saveVerbose();

  header("Content-type: image/png");
  echo $res['image'];

Источник: http://php.net/manual/en/rrdgraph.saveverbose.php

person Chupaka    schedule 26.04.2016