Как запустить скрипты Ruby/Python изнутри PHP, передавая и получая параметры?

мне нужно превратить HTML в эквивалентный текст с уценкой.

OBS.: быстрый и понятный способ сделать это с помощью PHP & Python.

поскольку я программирую на PHP, некоторые люди указывают Markdownify для выполнения работы, но, к сожалению, код не обновляется и на самом деле не работает. На sourceforge.net/projects/markdownify существует " Примечание: неподдерживаемый - вы хотите сохранить этот проект? контакт я! Markdownify-это конвертер HTML в Markdown, написанный на PHP. Смотрите его как преемника html2text.php, поскольку он имеет лучший дизайн, лучшую производительность и меньше угловых случаев."

от того, что я мог обнаружить, у меня есть только два хороших варианта:

  • Python: Аарон Шварц html2text.py

  • Ruby: html2markdown Singpolyma.rb, на основе Nokogiri

Итак, с PHP мне нужно передать HTML-код, позвонить скрипт Ruby / Python и получить вывод обратно.

(кстати, такой же вопрос задал здесь фолк ("как вызвать Ruby script с php?"), но без практической информации для моего случая).

следуя подсказке Железного Дровосека (рев), я добрался до этого:

PHP код:

$t='<p><b>Hello</b><i>world!</i></p>';
$scaped=preg_quote($t,"/");
$program='python html2md.py';

//exec($program.' '.$scaped,$n); print_r($n); exit; //Works!!!

$input=$t;

$descriptorspec=array(
   array('pipe','r'),//stdin is a pipe that the child will read from
   array('pipe','w'),//stdout is a pipe that the child will write to
   array('file','./error-output.txt','a')//stderr is a file to write to
);

$process=proc_open($program,$descriptorspec,$pipes);

if(is_resource($process)){
    fwrite($pipes[0],$input);
    fclose($pipes[0]);
    $r=stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    $return_value=proc_close($process);
    echo "command returned $return_valuen";
    print_r($pipes);
    print_r($r);
}

Python-кода:

#! /usr/bin/env python
import html2text
import sys
print html2text.html2text(sys.argv[1])
#print "Hi!" #works!!!

с вышеизложенным я получаю это:

команда возвращена 1 Матрица ( [0] => идентификатор ресурса #17 1 => Идентификатор ресурса #18 )

и "ошибка-выход.файл txt" говорит:

Traceback (последний звонок): Файл "html2md.py", строка 5, в печать html2text.html2text (sys.аргв1) IndexError: индекс списка вне диапазона

какие идеи???


код Ruby (все еще анализируется)

#!/usr/bin/env ruby
require_relative 'html2markdown'
puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s

просто для записей, я пытался использовать самый простой "exec ()" PHP, но у меня есть некоторые проблемы с некоторыми специальными символами, очень распространенными для языка HTML.

PHP код:

echo exec('./hi.rb');
echo exec('./hi.py');

Ruby код:

#!/usr/bin/ruby
puts "Hello World!"

Python-кода:

#!usr/bin/python
import sys
print sys.argv[1]

оба работают хорошо. Но когда строка немного сложнее:

$h='<p><b>Hello</b><i>world!</i></p>';
echo exec("python hi.py $h");

это не сработало вообще.

это потому, что строка html должна иметь свои специальные символы scaped. Я получил его, используя это:

$t='<p><b>Hello</b><i>world!</i></p>';
$scaped=preg_quote($t,"/");

теперь все работает как я сказал здесь.

Я runnig: Fedora 14 Руби 1.8.7 В Python 2.7 на Perl 5.12.2 В PHP 5.3.4 то nginx 0.8.53

5 ответов


откройте PHP скрипт Ruby или Python через proc_open, конвейер HTML в STDIN в скрипте. Скрипт Ruby / Python считывает и обрабатывает данные и возвращает их через STDOUT обратно в скрипт PHP, а затем завершает работу. Это распространенный способ делать вещи через popen-как функциональность в Perl, Ruby или Python и приятно, потому что это дает вам доступ к STDERR в случае, если что-то дует куски и не требует временных файлов, но это немного больше сложный.

альтернативными способами сделать это может быть запись данных из PHP во временный файл, а затем с помощью system, exec, или что-то похожее на вызов сценария Ruby/Python, чтобы открыть и обработать его, а также распечатать вывод, используя их STDOUT.

EDIT:

посмотреть @Jonke это для " Лучшие практики с STDIN в Ruby?"для примеров того, как просто читать STDIN и писать в STDOUT с Ruby. "как Вы читаете из stdin в python " есть несколько хороших образцов для этого языка.

это простой пример, показывающий, как вызвать скрипт Ruby, передать ему строку через канал STDIN PHP и прочитать STDOUT скрипта Ruby:

Сохранить как "тест.в PHP":

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "./error-output.txt", "a") // stderr is a file to write to
);
$process = proc_open('ruby ./test.rb', $descriptorspec, $pipes);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to /tmp/error-output.txt

    fwrite($pipes[0], 'hello world');
    fclose($pipes[0]);

    echo stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}
?>

Сохранить как "тест.rb":

#!/usr/bin/env ruby

puts "<b>#{ ARGF.read }</b>"

запуск скрипта PHP дает:

Greg:Desktop greg$ php test.php 
<b>hello world</b>
command returned 0

скрипт PHP открывает интерпретатор Ruby, который открывается рубиновый сценарий. Затем PHP отправляет ему "hello world". Ruby обертывает полученный текст жирным шрифтом и выводит его, который захватывается PHP,а затем выводит. Нет временных файлов, ничего не передается в командной строке, вы можете передать много данных, если это необходимо, и это будет довольно быстро. Python или Perl можно легко использовать вместо Ruby.

EDIT:

если у вас есть:

HTML2Markdown.new('<h1>HTMLcode</h1>').to_s

в качестве примера кода Вы можете начать разработку решения Ruby с:

#!/usr/bin/env ruby

require_relative 'html2markdown'

puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s

предполагая, что вы уже загрузили код HTML2Markdown и имеете его в текущем каталоге и используете Ruby 1.9.2.


в Python PHP передаст VAR в качестве аргумента командной строки, получите его из sys.argv (список аргументов командной строки, переданных Python), а затем Python распечатает вывод, который затем повторяет PHP. Пример:

#!usr/bin/python
import sys

print "Hello ", sys.argv[1] # 2nd element, since the first is the script name

PHP:

<?php
echo exec('python script.py Rafe');
?>

процедура должна быть в основном такой же в Ruby.


используйте переменную в коде Ruby и передайте ее в качестве аргумента скрипту Ruby из кода PHP. Затем попросите скрипт Ruby вернуть обработанный код в stdout, который PHP может прочитать.


Я думаю, что ваш вопрос является неправильным. Ваша проблема как конвертировать из HTML в уценке. Я прав?

попробуйте это http://milianw.de/projects/markdownify/ я думаю, что это может помочь вам =)


еще один очень странный подход будет похож на тот, который я использовал.

Php file -> output.txt
ruby file -> read from output.txt
Ruby file-> result.txt
Php file -> read from result.txt

simple add exec(rubyfile.rb);

Не рекомендуется, но это будет работать точно.