-1

次の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の引数が少なすぎます

助言がありますか?どうもありがとう。

4

8 に答える 8

6

pack()のPHPドキュメントから。

指定された引数を形式に従ってバイナリ文字列にパックします。

この関数のアイデアはPerlから採用され、すべてのフォーマットコードはPerlと同じように機能します。ただし、Perlの「u」フォーマットコードなど、欠落しているフォーマットコードがいくつかあります。

確かにそれはそのまま動作するはずですか?一部の変数の名前を変更する必要がある場合があります

于 2010-07-10T01:02:39.033 に答える
1

Perlでは、関数呼び出しがパラメーターリストの途中に配置され、呼び出された関数がリストを返す場合、そのリスト内の項目が「フラット化」されて複数の引数が生成されるという事実に問題があるようです。外部機能へ; PHPは同様のことを何もしません、そしてそれはあなたがあなたの引数の不一致を得るところです(分割はパックするために4つの引数を生成するはずですが、PHPは1つだけ-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 に答える
1

エラーステートメントは、確認する価値のあるものを意味する場合があります。引数が少なすぎるということは、PHPパックステートメントで使用される各入力が期待される形式と一致していることを確認する必要があることを意味する場合があります。

たとえば、perl packステートメントで使用される「ar」フィールドを考慮しましたか?そのため、結果のパックされたデータが1つのフィールドでずれている可能性があります。

于 2010-07-10T20:22:52.427 に答える
0

問題は、preg_splitが配列を返すことだと思います。したがって、配列は最初の文字として挿入され、時間は2番目の文字として挿入され、2つの文字が残ります。

この問題を修正する方法はわかりませんが、一時配列を作成するには:

$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

問題は、phppreg_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));

それがどうなるか教えてください。

于 2010-07-10T19:37:23.920 に答える
0

私の最初の提案は、ドキュメントを注意深く 読むことです。この問題はperlとはほとんど関係がなく、関数が何を期待するかを理解することと大いに関係があります。私の2番目の提案は、コードをコピーするたびに少し緊張する習慣を身につけることです。コードやドキュメントなどに特別な注意を払うのに十分な神経質です。少なくとも、クライアント/ボス/誰かがコピーされたコードのそのビットが何をするのかを尋ねるとき、あなたは良い答えを持っているはずです。

pack()の最初のパラメーターはフォーマット文字列です。これにより、出力を作成するときにパラメーターをフォーマットする方法が決まります。

pack()のドキュメントから:

フォーマット文字列は、フォーマットコードとそれに続くオプションのリピーター引数で構成されます。リピーター引数は、整数値または入力データの最後まで繰り返すための*のいずれかです。a、A、h、Hの場合、繰り返し回数は1つのデータ引数の文字数を指定します。 @の場合は次のデータを配置する絶対位置です。それ以外の場合、繰り返し回数は消費されるデータ引数の数を指定します。結果のバイナリ文字列にパックされます。

したがって、問題は、pack()に渡す引数に対してフォーマット文字列が適切でないことです。ここで、ニーズに合った適切なフォーマット文字列を推測する必要があることに注意してください。ドキュメントを読み、正しいフォーマット文字列を決定する必要があります。

以下は問題なく動作します。

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

関数preg_split()は単一の配列を返します。ただし、元のフォーマット文字列の「C4」は、4つのパラメータを受け取ることを想定しています。私のカウントに基づくと、元のフォーマット文字列は6つではなく9つのパラメータを意味していました。

于 2010-07-10T23:09:09.680 に答える
-1

私はこれをあまり長く見ていませんが、私が最初に気付いたのは、あなたが1つの開いたパレンと3つの閉じたパレンを持っているということでした。「時間」は$timeになるはずですか?

于 2010-07-10T02:09:42.147 に答える