将Perl代码转换为PHP

时间:2010-07-10 18:53:59

标签: php perl pack

我需要将以下perl函数转换为php:

pack("SSA12AC4L",
     $id,
     $loc,
     $name,
     'ar',
     split(/\./, $get->getIP),
     time+(60*60);

我在PHP中使用以下代码(测试):

echo pack("SSA12AC4L",
     '25',
     '00001',
     '2u7wx6fd94fd',
     'f',
     preg_split('/\./','10.2.1.1', -1, PREG_SPLIT_NO_EMPTY),
     time()+(60*60));

但是我收到以下错误: 警告:pack()[function.pack]:类型C:第8行的D:\ wamp \ www \ test.php中的参数太少

有什么建议吗?非常感谢。

8 个答案:

答案 0 :(得分:6)

来自pack()的PHP文档。

  

将给定参数打包成二进制   字符串格式。

     

采取了这个功能的想法   来自Perl和所有格式代码   和Perl一样工作。然而,   有一些格式代码   缺少诸如Perl的“u”格式   代码。

当然它应该按原样运作?您可能需要重命名一些变量

答案 1 :(得分:1)

有时,错误陈述意味着值得审阅的内容。参数太少可能意味着需要检查PHP包语句中使用的每个输入是否与预期的格式一致。

例如,您是否考虑了perl pack语句中使用的'ar'字段?由于这个原因,您可能会在一个字段中关闭生成的打包数据。

答案 2 :(得分:1)

看起来你遇到的问题是,在Perl中,如果函数调用放在参数列表的中间,并且被调用的函数返回一个列表,那么该列表中的项目将“展平”为为外部函数生成多个参数; PHP没有做类似的事情,那就是你的参数不匹配的地方(拆分应该产生四个参数来打包,但PHP只看到一个 - array值。

幸运的是,解决这个问题非常简单,因为内置的功能可以在没有任何体操的情况下复制您需要的内容。尝试:

echo pack("SSA12ANL",
'25',
'00001',
'2u7wx6fd94fd',
'f',
ip2long('10.2.1.1'),
'1278761963');

或者如果某种方式失败了:

echo pack("SSA12Aa4L",
'25',
'00001',
'2u7wx6fd94fd',
'f',
inet_pton('10.2.1.1'),
'1278761963');

答案 3 :(得分:0)

我认为问题在于preg_split返回一个数组。因此,数组作为第一个char插入,时间作为第二个,并留下两个字符。

我不知道如何解决这个问题,但是要创建一个临时数组:

$ip = explode('.','10.2.1.1');

然后:

echo pack("SSA12AC4L",
 '25',
 '00001',
 '2u7wx6fd94fd',
 'f',
 $ip[0],
 $ip[1],
 $ip[2]
 $ip[3],
 time()+(60*60));

答案 4 :(得分:0)

问题是代码给了pack()(我指的是最后一个参数)一个字符,一个数组和一个整数。由于代码C需要4个字符,这就是错误的原因。

代码应该是

$split = preg_split('/\./','10.2.1.1', -1, PREG_SPLIT_NO_EMPTY);
echo pack("SSA12AC4L",
  '25',
  '00001',
  '2u7wx6fd94fd',
  'f',
  $split[0],
  $split[1],
  $split[2],
  $split[3],
  time()+60*60
);

然后,在这种情况下,没有理由使用preg_split(),而可以使用explode()。正则表达式只应在严格必要时使用,因为正则表达式函数与其他字符串函数相比较慢。

答案 5 :(得分:0)

问题是php preg_split正在将其转换为数组。你需要一个unsigned char,所以使用

$x = intval(implode("", preg_split('/\./','10.2.1.1', -1, PREG_SPLIT_NO_EMPTY)));
echo pack('SSA12ACL',
     '25',
     '00001',
     '2u7wx6fd94fd',
     'f',
     $x,
     time()+(60*60));

让我们知道它是怎么回事。

答案 6 :(得分:0)

我的第一个建议是您仔细 阅读文档。这个问题与perl几乎没有关系,与理解函数期望的内容有很大关系。我的第二个建议是养成在复制代码时感到有些紧张的习惯。足够紧张,要特别注意代码,文档等。至少,当客户/老板/谁问你复制的代码有什么用时,你应该有一个很好的答案。

pack()的第一个参数是格式字符串。这决定了它在创建输出时如何格式化参数。

来自documentation for pack():

  

格式字符串由格式组成   代码后跟一个可选的转发器   论点。转发器参数可以是   要么是整数值,要么是*   重复到输入的结尾   数据。 对于a,A,h,H重复计数   指定一个字符的数量   获取数据参数,表示@是   绝对的位置放在哪里   下一个数据,用于其他所有内容   重复计数指定了多少数据   参数被消费并打包进去   生成的二进制字符串。

所以,问题是你的格式字符串不适合你传递给pack()的参数。现在,请记住,我必须根据您的需要猜测相应的格式字符串。您必须阅读文档并确定正确的格式字符串。

以下工作正常:

echo pack("SSA12ACL",
'25',
'00001',
'2u7wx6fd94fd',
'f',
preg_split('/\./','10.2.1.1', -1, PREG_SPLIT_NO_EMPTY),
'1278761963');

函数preg_split()返回一个数组。但是,原始格式字符串中的“C4”需要接收4个参数。根据我的计数,原始格式字符串隐含9个参数,而不是6个。

答案 7 :(得分:-1)

我没有看过这么长时间,但我注意到的第一件事是你有一个开放的paren和三个关闭。 “时间”应该是$ time?