繁体   English   中英

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

[英]How to run Ruby/Python scripts from inside PHP passing and receiving parameters?

我需要将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脚本?”),但我的案例没有实用信息)。

按照Tin Man的提示(下图),我得到了这个:

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”文件说:

回溯(最近一次调用最后一次):文件“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字符串需要将其特殊字符变为scaped。 我用它来得到它:

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

现在它像我在这里说的那样工作。

我是runnig:Fedora 14 ruby​​ 1.8.7 Python 2.7 perl 5.12.2 PHP 5.3.4 nginx 0.8.53

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

替代方法可以是将数据从PHP写入临时文件,然后使用systemexec或类似的东西调用Ruby / Python脚本打开并处理它,并使用他们的STDOUT打印输出。

编辑:

请参阅@ Jonke的回答 “在Ruby中使用STDIN的最佳实践?” 例如,读取STDIN并使用Ruby写入STDOUT是多么简单。 你如何从python中的stdin读取 ”有一些很好的样本用于该语言。

这是一个简单的例子,展示如何调用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。

在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代码中使用变量,并将其作为参数传递给PHP代码中的Ruby脚本。 然后,让Ruby脚本将处理过的代码返回到PHP可以读取的stdout中。

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM