Как запустить сценарии Ruby / Python изнутри PHP, передавая и получая параметры? - PullRequest
8 голосов
/ 07 января 2011

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

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

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

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

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

  • Ruby: html2markdown.rb Сингполимы, основанный на Nokogiri

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

(Кстати, народ тут задал похожий вопрос («как вызвать скрипт ruby ​​из 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_value\n";
    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] => ResourcИдентификатор # 17 1 => Идентификатор ресурса # 18)

И файл «error-output.txt» сообщает:

Traceback (последний вызов был последним):Файл "html2md.py", строка 5, печатается html2text.html2text (sys.argv 1 ) IndexError: список индексов выходит за пределы

Есть идеи ???


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

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

Только для записей я пытался использовать самый простой PHP "exec ()", но получилнекоторые проблемы с некоторыми специальными символами, очень распространенными в языке 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 нужно было убрать специальные символы.Я получил это, используя это:

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

Теперь это работает так, как я сказал здесь .

Я работаю: Fedora 14 ruby ​​1.8.7 Python 2.7 perl 5.12.2 PHP 5.3.4 nginx 0.8.53

Ответы [ 5 ]

12 голосов
/ 07 января 2011

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

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

EDIT:

См. @ ответ Джонке"Лучшие практики с использованием STDIN в Ruby?" примеры того, как просто читать STDIN и писать в STDOUT с Ruby. « Как вы читаете из stdin в python » содержит несколько хороших примеров для этого языка.

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

Сохраните это как "test.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";
}
?>

Сохранить как "test.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, который открывает скрипт Ruby. Затем PHP отправляет ему «привет мир». Ruby оборачивает полученный текст жирным тэгом и выводит его, который захватывает PHP, а затем выводит. Там нет временных файлов, ничего не передается в командной строке, вы можете передать много данных, если это будет необходимо, и это будет довольно быстро. Вместо Ruby можно легко использовать Python или Perl.

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.

5 голосов
/ 07 января 2011

В 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.

2 голосов
/ 07 января 2011

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

0 голосов
/ 05 октября 2016

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

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);

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

0 голосов
/ 07 января 2011

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

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

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