【问题标题】:Convert a Perl code to PHP将 Perl 代码转换为 PHP
【发布时间】:2011-03-14 07:44:32
【问题描述】:

我需要将以下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]: Type C: too little arguments in D:\wamp\www\test.php on line 8

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

【问题讨论】:

    标签: php perl pack


    【解决方案1】:

    来自pack() 的 PHP 文档。

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

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

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

    【讨论】:

    • @George:不过还是尽量帮忙吧。
    • 我知道,它应该可以工作,但它给了我以下错误:警告:pack() [function.pack]:C 型:D:\wamp\www\test.php 中的参数太少8号线
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        问题是代码给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】:

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

            • 正如其他发帖人所说,如果您不期望 IP 以外的任何东西,您可以使用 explode 代替 preg_split。
            【解决方案7】:

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

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

            来自documentation for pack():

            格式字符串由格式组成 后跟可选中继器的代码 争论。转发器参数可以是 整数值或 * 表示 重复到输入的末尾 数据。 对于a、A、h、H的重复次数 指定一个字符有多少个 采用 data 参数, 对于 @ 它是 放置的绝对位置 下一个数据,其他所有数据 重复计数指定多少数据 参数被消耗并打包到 生成的二进制字符串。

            所以,问题在于您的格式字符串不适合您传递给 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 个。

            【讨论】:

            • 这并不“工作得很好”,它在 IP 地址应该是一个完整的垃圾字符。将inet_pton($addr)a4ip2long($addr)N 打包怎么样?
            • @hobbs 正如我所指出的,我不知道他希望如何格式化输出。另外,请注意输出是 BINARY 字符串。 “在这种情况下,术语二进制字符串和字节字符串用于建议存储数据不(必然)代表文本的字符串。” en.wikipedia.org/wiki/String_%28computer_science%29
            • 我知道您必须猜测。但是猜测原始格式(来自工作代码)是错误的,并且以某种方式用单个字节表示 IP 地址是有意义的,这可能不是一个非常的猜测;猜测原始格式是正确的并且它旨在以规范方式(网络顺序为 4 个字节)表示 IP 地址是明智的。困难似乎来自 perl 将参数列表中的列表展平而 PHP 没有。我不知道您的“BINARY 字符串”咆哮应该告诉我们我们还不知道。
            • @hobbs 很公平,你说得很好。无论如何,即使输出可能无用,它也确实有效。此外,这不是猜测此代码的输出格式不正确,这是一个确定的事实。否则, pack() 不会抱怨。我对我的 perl 有点生疏了,所以我的猜测是没有得到应有的教育。
            【解决方案8】:

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

            【讨论】:

              猜你喜欢
              • 2017-05-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-07-18
              相关资源
              最近更新 更多