将Perl代码转换为PHP

将Perl代码转换为PHP,php,perl,pack,Php,Perl,Pack,我需要将以下perl函数转换为php: pack("SSA12AC4L", $id, $loc, $name, 'ar', split(/\./, $get->getIP), time+(60*60); 我在PHP中使用以下代码(用于测试): 但我得到了以下错误: 警告:pack()[function.pack]:类型C:第8行D:\wamp\www\test.php中的参数太少 有什么建议吗?非常感谢。来自PHP文档 将给定的

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

pack("SSA12AC4L",
     $id,
     $loc,
     $name,
     'ar',
     split(/\./, $get->getIP),
     time+(60*60);
我在PHP中使用以下代码(用于测试):

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


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

来自PHP文档

将给定的参数打包成二进制 根据格式设置字符串

这个功能的想法被采纳了 来自Perl和所有格式化代码 工作原理与Perl中的相同。然而, 有一些格式化代码 缺少诸如Perl的“u”格式之类的 代码


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

我没有看太久,但我注意到的第一件事是您有一个打开的paren和三个关闭的paren。“time”应该是$time吗?

我认为问题在于preg\u split返回一个数组。因此数组作为第一个字符插入,时间作为第二个字符插入,剩下两个字符

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

$ip = explode('.','10.2.1.1');
然后:

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

问题是代码给了
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
);

因此,在这种情况下,当可以使用
explode()
时,没有理由使用
preg\u split()
。只有在严格必要时才应使用正则表达式,因为正则表达式函数比其他字符串函数慢。

问题在于php preg_split正在将其转换为数组。您需要一个未签名的字符,所以请使用

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

让我们知道它是如何进行的。

有时错误陈述意味着值得回顾的东西。参数太少可能意味着需要检查PHP pack语句中使用的每个输入是否与预期格式一致


例如,您是否考虑了perl pack语句中使用的“ar”字段?因此,您可能会在结果中按一个字段压缩数据。

我的第一个建议是您仔细阅读文档。这个问题与perl没有多大关系,而与理解函数期望的内容有很大关系。我的第二个建议是养成一种习惯,每当你复制一些代码时,都会感到有点紧张。紧张到需要额外关注代码、文档等。至少,当客户/老板/任何人问你复制的代码是什么时,你应该有一个好的答案

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

从for pack()中:

格式字符串由格式组成 代码后跟可选的中继器 论点repeater参数可以是 一个整数值或*表示 重复到输入的末尾 数据对于a,a,h,h重复计数 指定一个字符的数量 采用数据参数,表示@it is 放置该对象的绝对位置 下一个数据,用于 重复计数指定有多少数据 参数被使用并打包到 生成的二进制字符串

因此,问题是格式字符串不适合传递给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。

< P>看起来,在Perl中,如果函数调用放置在参数列表中间,并且调用函数返回列表,则列表中的项被“夷平”,以向外部函数生成多个参数;PHP没有做任何类似的事情,这就是参数不匹配的原因(分割应该产生四个要打包的参数,但PHP只看到一个--
数组
值)

幸运的是,解决这个问题的方法非常简单,因为有内置函数可以复制您需要的功能,而无需任何操作。尝试:

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

@乔治:不过,还是试着帮点忙吧。我知道,它应该可以工作,但它给了我以下错误:警告:pack()[function.pack]:在第8行的D:\wamp\www\test.php中键入C:参数太少了,正如其他海报所说,如果你不希望得到IP以外的任何东西,你可以使用explode而不是preg\u split。这不正确“工作正常”,它将一个完整的垃圾字符放在IP地址应该是的位置。用
a4
打包
inet\u pton($addr)
,或者用
N
打包
ip2long($addr)
?@hobbs,正如我所说的,我不知道他想要如何格式化输出。另外,请注意,输出是一个二进制字符串。”,术语二进制字符串和字节字符串用于表示存储的数据(不一定)不代表文本的字符串。“我知道你必须猜测。但是猜测原始格式(来自工作代码)是错误的,用一个字节表示一个IP地址在某种程度上是有意义的,这可能不是一个很好的猜测;猜测原始格式是正确的,并且它意味着以规范的方式表示一个IP地址(网络顺序为4个字节)是合理的。困难似乎来自于perl将参数列表中的列表展平,而PHP没有。我不知道你的“二进制字符串”咆哮应该告诉我们什么,我们还不知道。@hobbs,很公平,你的观点很好。不管怎样,我
echo pack("SSA12Aa4L",
'25',
'00001',
'2u7wx6fd94fd',
'f',
inet_pton('10.2.1.1'),
'1278761963');