Perl - LWP API帖子

时间:2014-03-21 12:52:59

标签: php perl lwp

我试图使用LWP将新商品发布到商家信息网站。列表网站提供了如何发布数据但使用PHP的示例,因此我尝试在Perl中重现解决方案。

这是PHP示例。

$postData = array('type'   => 'fixedPrice',
                  'item'   => array(
                      'id_country'         => 0,
                      'id_category'        => 80,
                      'fixed_price'        => '1.00', 
                      'currency'           => 'EUR',
                      'title'              => 'My title',
                      'personal_reference' => 'My personal ref',
));

//RESOURCE CALL WITH POST METHOD

$url = 'http://correct.server.address/item?token=MyPersonalToken';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($postData) );
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$xml_response  = curl_exec($ch);

My Perl解决方案:

#!/usr/bin/perl

### Module requests ###

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common;
use XML::LibXML;
use Data::Dumper;

### Make Request to get the session Token ###

my $url = "http://correct.server.address/seller";
my $api = "APIKEY";

my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => $url . "?apikey=" . $api);
my $response = $userAgent->request($request);

### Display error if request to server fails ###

unless ($response->is_success) {
    print "Content-type: text/html\n\n";
    print "Error: " . $response->status_line;
    exit;
}

### Assign response xml to $xml_token ###

my $xml_token = $response->content;

### Parse XML through XML::LibXML module ###

my $parser = XML::LibXML->new();
my $tree = $parser->parse_string($xml_token);
my $root = $tree->getDocumentElement;
my $token = $root->getElementsByTagName('token');

### Make Request to add Item - PROBLEM STARTS HERE ###

my $postURL = "http://correct.server.address/item" . "?token=" . $token;

my %item_data = (type => "fixedPrice",
                item => {
                    id_country => "0",
                    id_category => "728",
                    fixed_price => "1.00",
                    currency => "GBP",
                    title => "Test item",
                    personal_reference => "12345"
                }
            );

my $userAgentReq2 = LWP::UserAgent->new();
my $requestReq2 = HTTP::Request->new(POST => $postURL);
$requestReq2->header(content_type => 'multipart/form-data');
$requestReq2->content(\%item_data);
my $responseReq2 = $userAgentReq2->request($requestReq2);

### Display error if request to server fails ###

unless ($responseReq2->is_success) {

    print "Content-type: text/html\n\n";
    print "<p>Error Message: " . $responseReq2->status_line;
    print "</p><p>Output of test data sent: \n";
    print Dumper(\%item_data);
    print "</p><p>Dumped Response: \n";
    print Dumper($responseReq2);
    print "</p><p>\n";
    print "Token: $token\n";
    print "</p><p>\n";
    print "Response: " . $responseReq2->as_string;
    print "</p>\n";
    exit;
}

### Assign response xml to $xml_responseReq2 ###

my $xml_responseReq2 = $responseReq2->content;

### Display Token ###

print "Content-type: text/html\n\n";
print "<p>Response: $xml_responseReq2</p>\n";
print Dumper($responseReq2);
exit;

我的第一个检索会话令牌的帖子请求正常工作,我收到了令牌。但是我的第二个帖子请求尝试添加项目失败。

这是倾销的回复:

$VAR1 = bless( {
                 '_content' => 'Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
',
                 '_rc' => 500,
                 '_headers' => bless( {
                                        'client-warning' => 'Internal response',
                                        'client-date' => 'Fri, 21 Mar 2014 12:13:34 GMT',
                                        'content-type' => 'text/plain',
                                        '::std_case' => {
                                                          'client-warning' => 'Client-Warning',
                                                          'client-date' => 'Client-Date'
                                                        }
                                      }, 'HTTP::Headers' ),
                 '_msg' => 'Not a SCALAR reference',
                 '_request' => bless( {
                                        '_content' => {
                                                        'item' => {
                                                                    'currency' => 'GBP',
                                                                    'id_category' => '728',
                                                                    'id_country' => '0',
                                                                    'personal_reference' => '12345',
                                                                    'title' => 'Test item',
                                                                    'fixed_price' => '1.00'
                                                                  },
                                                        'type' => 'fixedPrice'
                                                      },
                                        '_uri' => bless( do{\(my $o = 'http://correct.server.address/item?token=986aee823d54a7c2d50651c1b272c455')}, 'URI::http' ),
                                        '_headers' => bless( {
                                                               'user-agent' => 'libwww-perl/6.05',
                                                               'content-type' => 'multipart/form-data'
                                                             }, 'HTTP::Headers' ),
                                        '_method' => 'POST'
                                      }, 'HTTP::Request' )
               }, 'HTTP::Response' );

请有人帮我解决我出错的地方,非常感谢!

2 个答案:

答案 0 :(得分:1)

PHP允许您创建自动反序列化为嵌套结构的POST变量;例如,您可以使用名为item[0]item[1]等表单字段,这些字段将作为值数组显示在服务器端PHP脚本中。但HTTP没有任何数组概念;发布数据是简单的密钥和值对。

示例客户端PHP代码正在尝试构建嵌套数组结构,PHP的curl接口将自动转换为HTTP字段名称。自从我完成任何PHP以来已经有一百万年了,但我认为字段名称最终会是item[0][id_country]item[0][id_category],依此类推。这就是PHP“欺骗”HTTP以将复杂结构放入POST的方式。

Perl的LWP库支持以嵌套结构构建字段名称。这就是你收到这个错误的原因:

  

不是/usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm第203行的SCALAR参考。   “

在你的POST参数中,item键指向一个哈希引用,但LWP只希望在那里看到一个普通的标量或标量引用。

因此,您需要将LWP POST参数更改为以下内容。 (如果这不完全正确,您可以在PHP代码上使用HTTP嗅探器来确定它生成的实际字段名称。)

my %item_data = (type => "fixedPrice",
                 'item[0][id_country]' => "0",
                 'item[0][id_category]' => "728",
                 'item[0][fixed_price]' => "1.00",
                 'item[0][currency]' => "GBP",
                 'item[0][title]' => "Test item",
                 'item[0][personal_reference]' => "12345"
            );

答案 1 :(得分:1)

以下似乎可以实现您的目标。

my %item_data = (type => "fixedPrice",
                'item[id_country]' => "0",
                'item[id_category]' => "728",
                'item[fixed_price]' => "1.00",
                'item[currency]' => "GBP",
                'item[title]' => "Test item",
                'item[personal_reference]' => "12345"
        );

my $userAgentReq2 = LWP::UserAgent->new();
my $responseReq2 = $userAgentReq2->post($postURL,[%item_data]);