如何从 PHP 内部运行 Ruby/Python 脚本传递和接收参数?

发布于 2024-10-10 21:53:17 字数 3452 浏览 5 评论 0原文

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

OBS.:使用 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!!!

有了上面的内容,我得到了这个:

command returned 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,"/");

现在它的工作原理就像我说的 此处

我正在跑步: 软呢帽 14 红宝石 1.8.7 Python 2.7 珀尔 5.12.2 PHP 5.3.4 nginx 0.8.53

I need to turn HTML into equivalent Markdown-structured text.

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

As I am programming in PHP, some people indicates Markdownify to do the job, but unfortunately, the code is not being updated and in fact it is not working. At sourceforge.net/projects/markdownify there is a "NOTE: unsupported - do you want to maintain this project? contact me! Markdownify is a HTML to Markdown converter written in PHP. See it as the successor to html2text.php since it has better design, better performance and less corner cases."

From what I could discover, I have only two good choices:

  • Python: Aaron Swartz's html2text.py

  • Ruby: Singpolyma's html2markdown.rb, based on Nokogiri

So, from PHP, I need to pass the HTML code, call the Ruby/Python Script and receive the output back.

(By the way, a folk made a similar question here ("how to call ruby script from php?") but with no practical information to my case).

Following the Tin Man`s tip (bellow), I got to this:

PHP code:

$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 code:

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

With the above I am geting this:

command returned 1
Array
(
[0] => Resource id #17
1 => Resource id #18
)

And the "error-output.txt" file says:

Traceback (most recent call last):
File "html2md.py", line 5, in
print html2text.html2text(sys.argv1)
IndexError: list index out of range

Any ideas???


Ruby code (still beeing analysed)

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

Just for the records, I tryed before to use PHP's most simple "exec()" but I got some problemas with some special characters very common to HTML language.

PHP code:

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

Ruby code:

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

Python code:

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

Both working fine. But when the string is a bit more complicated:

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

It did not work at all.

That's because the html string needed to have its special characters scaped. I got it using this:

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

Now it works like I said here.

I am runnig:
Fedora 14
ruby 1.8.7
Python 2.7
perl 5.12.2
PHP 5.3.4
nginx 0.8.53

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

迷雾森÷林ヴ 2024-10-17 21:53:17

让 PHP 通过 proc_open,将 HTML 通过管道传输到脚本中的 STDIN 中。 Ruby/Python 脚本读取并处理数据,并通过 STDOUT 将其返回给 PHP 脚本,然后退出。这是在 Perl、Ruby 或 Python 中通过类似 popen 的功能执行操作的常见方法,这很好,因为它可以让您访问 STDERR,以防出现块损坏的情况,并且不需要临时文件,但是有点复杂。

另一种方法是将 PHP 中的数据写入临时文件,然后使用 系统执行,或类似调用 Ruby/Python 脚本来打开并处理它,并使用其 STDOUT 打印输出。

编辑:

请参阅 @Jonke 的回答,了解“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。

Have PHP open the Ruby or Python script via proc_open, piping the HTML into STDIN in the script. The Ruby/Python script reads and processes the data and returns it via STDOUT back to the PHP script, then exits. This is a common way of doing things via popen-like functionality in Perl, Ruby or Python and is nice because it gives you access to STDERR in case something blows chunks and doesn't require temp files, but it's a bit more complex.

Alternate ways of doing it could be writing the data from PHP to a temporary file, then using system, exec, or something similar to call the Ruby/Python script to open and process it, and print the output using their STDOUT.

EDIT:

See @Jonke's answer for "Best practices with STDIN in Ruby?" for examples of how simple it is to read STDIN and write to STDOUT with Ruby. "How do you read from stdin in python" has some good samples for that language.

This is a simple example showing how to call a Ruby script, passing a string to it via PHP's STDIN pipe, and reading the Ruby script's STDOUT:

Save this as "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";
}
?>

Save this as "test.rb":

#!/usr/bin/env ruby

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

Running the PHP script gives:

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

The PHP script is opening the Ruby interpreter which opens the Ruby script. PHP then sends "hello world" to it. Ruby wraps the received text in bold tags, and outputs it, which is captured by PHP, and then output. There are no temp files, nothing passed on the command-line, you could pass a LOT of data if need-be, and it would be pretty fast. Python or Perl could easily be used instead of Ruby.

EDIT:

If you have:

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

as sample code, then you could begin developing a Ruby solution with:

#!/usr/bin/env ruby

require_relative 'html2markdown'

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

assuming you've already downloaded the HTML2Markdown code and have it in the current directory and are running Ruby 1.9.2.

神妖 2024-10-17 21:53:17

在 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 中的过程应该基本相同。

In Python, have PHP pass the var as a command line argument, get it from sys.argv (the list of command line arguments passed to Python), and then have Python print the output, which PHP then echoes. Example:

#!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');
?>

The procedure should be basically the same in Ruby.

贱人配狗天长地久 2024-10-17 21:53:17

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

Use a variable in the Ruby code, and pass it in as an argument to the Ruby script from the PHP code. Then, have the Ruby script return the processed code into stdout which PHP can read.

等你爱我 2024-10-17 21:53:17

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

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

I think your question is wrong. Your problem is how to convert from HTML to Markdown. Am I right?

Try this http://milianw.de/projects/markdownify/ I think it could help you =)

分分钟 2024-10-17 21:53:17

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

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

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

Another very weird approach will be like the one i used.

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

Not recommended but this will work for sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文