PHP-вызов R, изображение, созданное при выполнении в терминале, но не из веб-интерфейса - PullRequest
2 голосов
/ 27 декабря 2011

Я пытаюсь запустить R-скрипт из PHP, и в R-скрипте я создам изображение test.jpg, а в PHP я покажу это изображение в Интернете.

R - 2.11.1, а ОС - Ubuntu 10.10.

Проблема в том, что этот файл .jpg создается успешно, если я запускаю из терминала, но изображение не создается, если я запускаю из WebUI. Я запускаю скрипт из терминала и WebUI в одном каталоге. / Опт / lampp / HTDOCS / имя /. (Если кто-нибудь подскажет мне хороший инструмент для отладки этого WebUI, было бы замечательно. Я добавил эхо в файл .php, я вижу вызываемые функции, но все еще не знаю, как решить эту ошибку).

.jpg создается при запуске из терминала:

php r_caller.php

В этом файле r_caller.php у меня есть простая функция:

<?php php_call_r(){
$cmd = "echo 'argv <- \"r_command.r\"; source(argv)' | " .
     "/usr/bin/R --vanilla --slave";
$ret = system($cmd);
echo $ret;}
?>

и эта функция php_call_r вызывается в том же файле, что и r_caller.php:

<?php
//some irrelavant codes above
php_call_r();
print("<img src=test.jpg>");
?}

и в скрипте r_command.r у меня есть простые команды:

jpeg("test.jpg") 
plot(50, 50)
dev.off()

Я очень ценю вашу помощь!

Ответы [ 3 ]

1 голос
/ 27 декабря 2011

Вы не указали свою платформу и версию R, но в Unix устройству jpeg() может потребоваться X11 для рендеринга изображения (которое может быть в вашем интерактивном сеансе, но не в Apache). Возможно, вам лучше использовать пакет Cairo или другие средства, для которых не требуется сеанс X11 (недавний R позволяет использовать альтернативные типы в вызове jpeg, который вы также можете попробовать - см. ?jpeg).

(В качестве дополнительного примечания есть PHP-клиент для Rserve, который значительно ускоряет выполнение веб-запросов - запуск самого R в значительной степени самый медленный способ использования R из PHP. Если вы не хотите устанавливать какие-либо пакеты, вы можете хотите использовать хотя бы Rscript)

Редактировать: Теперь, когда вы добавили версию R - это действительно древняя версия, вам следует серьезно подумать об ее обновлении. Вы можете попробовать установить Cairo с этой старой версией R, но, возможно, вам, возможно, придется вернуться туда.

Еще одна вещь, которую следует учесть, проверьте свои права доступа к файлу - убедитесь, что www-data имеет разрешения на запись, где бы вы ни создавали файл (например, см. echo system("pwd");, в котором будет запущен текущий каталог R).

0 голосов
/ 27 декабря 2011

Выполнение R из PHP для каждого запроса - очень плохая идея - PHP-конвейер обычно ненадежен, а выходные данные R оптимизированы для интерактивной работы, а не для передачи результатов. Более того, R начинается целую вечность, поэтому вы тратите много времени и ресурсов процессора.

Лучшей идеей является использование рабочего демона R, созданного либо Rserve, либо triggr - Rserve имеет клиент PHP , для triggr вам нужно приготовить его самостоятельно, но это тривиально; это может выглядеть так:

R part (r.R)

require(triggr);
serve(function(data_from_php){
 cat(sprintf("Called with: %s\n",data_from_php));

 #<<Picture creation code>>

 #Break connection notifying PHP that picture is done
 return(endConnection("Done\r\n"));
},9090);
  # ^- Port you want to use for internal communication

PHP часть

<?php
$s=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
echo "Connecting...\n";

if(socket_connect($s,"localhost",9090)){
 echo "Connected!\n"; //v double \r\n is crucial
 $d="some data for R\r\n\r\n";
 socket_write($s,$d,strlen($d));
 //This blocks until picture is done
 $r=socket_read($s,6);

 //Here we can emit the page featuring <img>
 echo "Response was $r\n";
}
?>

Теперь вы просто запускаете r.R в фоновом режиме или под каким-то демоном автоматического воскрешения, и все готово.

0 голосов
/ 27 декабря 2011

Проверьте журналы ошибок Apache, чтобы увидеть, есть ли какие-либо ошибки.Попробуйте добавить следующее в начало вашего кода PHP:

error_reporting(E_ALL);
ini_set('display_errors','On');

Это может быть ошибка копирования / вставки, но ваша функция php_call_r не определена должным образом как функция.Я предлагаю следующее:

<?php function php_call_r() {
    $cmd = "echo 'argv <- \"r_command.r\"; source(argv)' | " .
    "/usr/bin/R --vanilla --slave";
    $ret = system($cmd);
    echo $ret;
}
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...