-1

I need to convert the following perl function to php:

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

I use the following code (to test) in PHP:

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

But I'm getting the following error: Warning: pack() [function.pack]: Type C: too few arguments in D:\wamp\www\test.php on line 8

Any suggestions? Thanks a lot.

4

8 回答 8

6

来自pack()的 PHP 文档。

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

这个函数的想法取自 Perl,所有格式化代码的工作方式与 Perl 中的相同。但是,缺少一些格式代码,例如 Perl 的“u”格式代码。

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

于 2010-07-10T01:02:39.033 回答
1

Sometimes the error statements mean something worth reviewing. Too few arguments may mean there is a need to review each input used in the PHP pack statement aligns with the expected format.

For instance, did you take into account the 'ar' field used in the perl pack statement? You might be off in the resulting packed data by one field because of that.

于 2010-07-10T20:22:52.427 回答
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');
于 2010-07-11T00:01:51.583 回答
0

我认为问题在于 preg_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));
于 2010-07-10T19:26:23.520 回答
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()可以代替使用。正则表达式仅在绝对必要时才应使用,因为与其他字符串函数相比,正则表达式函数速度较慢。

于 2010-07-10T19:30:15.120 回答
0

问题是 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));

让知道它是怎么回事。

于 2010-07-10T19:37:23.920 回答
0

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

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

从pack()的文档中:

格式字符串由格式代码和一个可选的转发器参数组成。repeater 参数可以是整数值或 * 用于重复到输入数据的末尾。对于 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 个。

于 2010-07-10T23:09:09.680 回答
-1

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

于 2010-07-10T02:09:42.147 回答