将 Perl 代码转换为 PHP

发布于 2024-09-08 13:17:07 字数 489 浏览 3 评论 0原文

我需要将以下 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 中的参数太少

有什么建议吗?多谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

慕巷 2024-09-15 13:17:07

来自 pack() 的 PHP 文档。

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

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

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

From the PHP documentation for pack().

Pack given arguments into binary
string according to format.

The idea for this function was taken
from Perl and all formatting codes
work the same as in Perl. However,
there are some formatting codes that
are missing such as Perl's "u" format
code.

Surely it should just work as is? You may need to rename some variables

戒ㄋ 2024-09-15 13:17:07

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

例如,您是否考虑了 perl pack 语句中使用的“ar”字段?因此,您可能会在生成的打包数据中偏离一个字段。

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.

云裳 2024-09-15 13:17:07

看起来您遇到了这样的问题:在 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');

It looks like you're having trouble with the fact that in Perl, if a function call is placed in the middle of a parameter list, and the called function returns a list, the items in that list are "flattened" to produce multiple arguments to the outer function; PHP doesn't do anything similar, and that's where you're getting your argument mismatch (the split should be producing four arguments to pack, but PHP only sees one -- an array value).

Fortunately the way around this is pretty easy, because there are builtin functions that will replicate what you need without any gymnastics. Try:

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

or if that somehow fails:

echo pack("SSA12Aa4L",
'25',
'00001',
'2u7wx6fd94fd',
'f',
inet_pton('10.2.1.1'),
'1278761963');
感性不性感 2024-09-15 13:17:07

问题是代码给了 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() 来代替。仅当绝对必要时才应使用正则表达式,因为与其他字符串函数相比,正则表达式函数速度较慢。

The problem is that the code is giving to pack() (I am referring the the last arguments) a character, an array, and an integer. As the code C wants 4 characters, that is the cause of the error.

The code should be something like

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

Then, there is no reason to use preg_split() in this case, when explode() can be used instead. Regular expressions should be used only when strictly necessary because the regular expression functions are slower, compared to other string functions.

再可℃爱ぅ一点好了 2024-09-15 13:17:07

我认为问题在于 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));

I think that the problem is that preg_split returns an array. So the array is inserted as the first char, the time as the second, and two chars are left.

I don't know how to fix this problem, but to create a temporary array:

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

And then:

echo pack("SSA12AC4L",
 '25',
 '00001',
 '2u7wx6fd94fd',
 'f',
 $ip[0],
 $ip[1],
 $ip[2]
 $ip[3],
 time()+(60*60));
还在原地等你 2024-09-15 13:17:07

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

“让知道它是如何进行的”。

The problem is that php preg_split is converting it to an array. You need an unsigned char, so use

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

Let know how it goes.

少跟Wǒ拽 2024-09-15 13:17:07

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

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

来自 pack() 的 文档

格式字符串由格式组成
代码后跟一个可选的中继器
争论。中继器参数可以是
整数值或 * 为
重复到输入结束
数据。 对于 a、A、h、H 重复计数
指定一个字符有多少个
数据参数被采用,
for @ 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 个。

My first suggestion is that you carefully read the documentation. This problem has little to do with perl and much to do with understanding what the function expects. My second suggestion is to get in the habit of feeling a little nervous whenever you copy some code. Nervous enough to pay extra attention to the code, the documentation, etc. At the very least, when a client/boss/whoever asks you what that bit of copied code does, you should have a good answer.

The first parameter to pack() is a format string. This determines how it formats the parameters when it creates the output.

From the documentation for pack():

The format string consists of format
codes followed by an optional repeater
argument. The repeater argument can be
either an integer value or * for
repeating to the end of the input
data. For a, A, h, H the repeat count
specifies how many characters of one
data argument are taken,
for @ it is
the absolute position where to put the
next data, for everything else the
repeat count specifies how many data
arguments are consumed
and packed into
the resulting binary string.

So, the problem is that your format string isn't appropriate for the arguments you pass to pack(). Now, keep in mind that I have to guess at the appropriate format string for your needs. You have to read the documentation and determine the correct format string.

The following works just fine:

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

The function preg_split() returns a single array. However, the 'C4' in the original format string expects to take in 4 parameters. Based on my count, the original format string implied 9 parameters, not 6.

云朵有点甜 2024-09-15 13:17:07

我没有看这个很长时间,但我注意到的第一件事是你有一个左括号和三个右括号。 “时间”应该是 $time 吗?

I haven't looked at this very long, but the first thing I noticed was that you have one open paren and three closing. Is "time" supposed to be $time?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文