【问题标题】:How to run Ruby/Python scripts from inside PHP passing and receiving parameters?如何从 PHP 内部运行 Ruby/Python 脚本传递和接收参数?
【发布时间】:2011-06-04 22:26:27
【问题描述】:

我需要将 HTML 转换为等效的 Markdown 结构文本。

OBS.:Quick and clear way of doing this with PHP & Python.

当我在 PHP 中编程时,有些人表示 Markdownify 来完成这项工作,但不幸的是,代码没有更新,实际上 它不起作用。在 sourceforge.net/projects/markdownify 有一个“注意:不支持 - 你想维护这个项目吗?联系我!Markdownify 是一个用 PHP 编写的 HTML 到 Markdown 转换器。将其视为 html2text.php 的继任者,因为它有更好的设计、更好的性能和更少的极端情况。”

据我所知,我只有两个不错的选择:

  • Python:Aaron Swartz 的 html2text.py

  • Ruby:Singpolyma 的 html2markdown.rb,基于 Nokogiri

所以,我需要从 PHP 传递 HTML 代码,调用 Ruby/Python 脚本并接收返回的输出。

(顺便说一句,有人在这里提出了类似的问题(“如何从 php 调用 ruby​​ 脚本?”),但对我的情况没有实际信息)。

按照铁皮人的提示(如下),我得到了这个:

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] => 资源 ID #17 1 => 资源 ID #18 )

并且“error-output.txt”文件说:

Traceback(最近一次调用最后一次): 文件“html2md.py”,第 5 行,在 打印 html2text.html2text(sys.argv1) 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,"/");

现在它就像我说的 here.

我在跑步: 软呢帽 14 红宝石 1.8.7 蟒蛇 2.7 perl 5.12.2 PHP 5.3.4 nginx 0.8.53

【问题讨论】:

  • WMD markdown editor - HTML to Markdown conversion 的可能重复项建议 Markdownify 使用 PHP 从 HTML 转换为 Markdown。
  • 好吧,他们正在讨论“WMD markdown 编辑器 - HTML 到 Markdown 转换”的不同内容,尽管他们实际上正在尝试将 HTML 转换为 Markdown。另请注意,该主题仍未解决,并且没有任何好的 PHP 程序可以完成这项工作。提到了“Markdownify”,但实际上该项目是作者留下的,代码不起作用。
  • 尝试在命令行上传递要更改的字符串是一个非常脆弱的解决方案,并且很容易中断。
  • 如果有更好的方法使用 PHP 的“exec()”来做到这一点,那么我同意你的观点,这不是一个解决方案。

标签: php python html ruby markdown


【解决方案1】:

让 PHP 通过proc_open 打开 Ruby 或 Python 脚本,将 HTML 通过管道传输到脚本中的 STDIN。 Ruby/Python 脚本读取并处理数据并通过 STDOUT 将其返回给 PHP 脚本,然后退出。这是在 Perl、Ruby 或 Python 中通过类似于popen 的功能来做事的一种常见方式,并且很好,因为它可以让您访问 STDERR,以防万一发生大块并且不需要临时文件,但它有点复杂.

另一种方法是将数据从 PHP 写入临时文件,然后使用 systemexec 或类似调用 Ruby/Python 脚本来打开和处理它,并打印输出使用他们的标准输出。

编辑:

请参阅@Jonke's answer 了解“在 Ruby 中使用 STDIN 的最佳实践?”有关使用 Ruby 读取 STDIN 和写入 STDOUT 是多么简单的示例。 “How do you read from stdin in python”为该语言提供了一些很好的示例。

这是一个简单的示例,展示了如何调用 Ruby 脚本,通过 PHP 的 STDIN 管道将字符串传递给它,并读取 Ruby 脚本的 STDOUT:

将此保存为“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 向它发送“hello world”。 Ruby 将接收到的文本用粗体标签包裹,然后输出,由 PHP 捕获,然后输出。没有临时文件,命令行上没有传递任何内容,如果需要,您可以传递大量数据,而且速度会非常快。可以轻松地使用 Python 或 Perl 代替 Ruby。

编辑:

如果你有:

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。

【讨论】:

  • 非常感谢。请给我一个例子好吗?
  • @Roger,“proc_open”、“system”和“exec”的 PHP 链接在页面底部有示例代码。有关 Ruby 和 PHP 的示例,请参阅我的答案中的编辑。
  • 我执行了您的代码,输出为:“命令返回 1”。看起来“proc_open()”让我们对数据有更多的控制权,尽管因为我从未使用过它,所以一开始它看起来很混乱。我还在构思如何让 Ruby(或 Python)处理 HTML 输入。
  • 输出显示“command returned 1”,因为有些事情没有正确完成。尝试从保存“test.rb”文件的同一目录运行echo 'foo' | ruby test.rb。你应该得到“&lt;b&gt;foo&lt;/b&gt;”。
  • 当然,我明白了:“hello world 命令返回 0”。现在描绘如何在 Ruby 或 Python 中实现它。
【解决方案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中应该基本相同。

【讨论】:

  • Rafe,拜托,我已经在你上面的回复中添加了评论。
  • @Roger 我知道你做了什么,但我不确定是什么导致了错误。输出是什么?
  • @Roger 我看过了,问题是!特点;这对 bash shell 具有特殊的意义。所以你可以做的是转义特殊字符,或者选择一个更健壮的解决方案(我确信有 PHP 的 markdown 模块)
  • 正如我上面所说,如果有更好的方法来做到这一点(将html文本传递给其他程序)使用PHP的“exec()”,那么我同意你,这不是一个解决方案.顺便说一句,我正在寻找一种将 HTML 转换为 Markdown 的方法,而不是相反。
  • @Roger 你应该看看 Markdownify (milianw.de/projects/markdownify)。您可以将文本从 PHP 传递到 Python 并返回,但使用 PHP 模块会更容易。
【解决方案3】:

在 Ruby 代码中使用变量,并将其作为参数从 PHP 代码传递给 Ruby 脚本。然后,让 Ruby 脚本将处理后的代码返回到 PHP 可以读取的标准输出中。

【讨论】:

    【解决方案4】:

    我认为你的问题是错误的。您的问题是如何从 HTML 转换为 Markdown。我说的对吗?

    试试这个http://milianw.de/projects/markdownify/我想它可以帮助你=)

    【讨论】:

    • 正如我所说,它坏了。在 sourceforge.net/projects/markdownify 有一个“注意:不支持 - 你想维护这个项目吗?联系我!Markdownify 是一个用 PHP 编写的 HTML 到 Markdown 转换器。将它视为 html2text.php 的继任者,因为它有更好的设计、更好的性能和更少的极端情况。”
    • Evaldo,这解决了我的问题:stackoverflow.com/questions/4686842/…
    【解决方案5】:

    另一种非常奇怪的方法就像我使用的那样。

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

    不推荐,但这肯定会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多