Конвертировать Perl-код в PHP - PullRequest
0 голосов
/ 10 июля 2010

Мне нужно преобразовать следующую функцию 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: слишком мало аргументов в D: \ wamp \ www \ test.php в строке 8

Есть предложения? Большое спасибо.

Ответы [ 8 ]

6 голосов
/ 10 июля 2010

Из документации PHP для pack () .

Упаковать заданные аргументы в двоичную строку в соответствии с форматом.

Идея для этой функции была взятаиз Perl и все коды форматирования работают так же, как в Perl.Однако, есть некоторые коды форматирования, которые отсутствуют, такие как код формата Perl "u".

Конечно, он должен работать как есть?Возможно, вам придется переименовать некоторые переменные

1 голос
/ 11 июля 2010

Похоже, у вас возникли проблемы с тем фактом, что в 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');
1 голос
/ 11 июля 2010

Иногда сообщения об ошибках означают что-то, что стоит рассмотреть.Слишком мало аргументов может означать, что необходимо проверить, чтобы каждый ввод, используемый в выражении пакета PHP, совпадал с ожидаемым форматом.

Например, учли ли вы поле 'ar', используемое в операторе perl pack?Из-за этого вы можете быть отключены в полученных упакованных данных на одно поле.

0 голосов
/ 11 июля 2010

Мое первое предложение состоит в том, чтобы вы внимательно прочитали документацию.Эта проблема имеет мало общего с Perl и имеет много общего с пониманием того, что ожидает функция.Мое второе предложение - привыкнуть немного нервничать, когда вы копируете какой-то код.Достаточно нервный, чтобы уделять дополнительное внимание к коду, документации и т. Д. По крайней мере, когда клиент / начальник / кто-то спрашивает вас, что делает этот бит скопированного кода, у вас должен быть хороший ответ.

Первый параметр pack () - это строка формата.Это определяет способ форматирования параметров при создании выходных данных.

Из документации для pack ():

Строка формата состоит из следующих кодов форматанеобязательным аргументом повторителя.Аргумент повторителя может быть целочисленным значением или * для повторения до конца входных данных. Для a, A, h, H счетчик повторений указывает, сколько символов одного аргумента данных будет взято, для @ это абсолютная позиция, куда следует поместить следующие данные, для всего остального, повторcount указывает, сколько аргументов данных будет использовано и упаковано в полученную двоичную строку.

Итак, проблема в том, что ваша строка формата не подходит для аргументов, которые вы передаете 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.

0 голосов
/ 10 июля 2010

Проблема в том, что 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));

Дайте знать, как это происходит.

0 голосов
/ 10 июля 2010

Проблема в том, что код дает 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().Регулярные выражения следует использовать только в случае крайней необходимости, поскольку функции регулярных выражений работают медленнее, чем другие строковые функции.

0 голосов
/ 10 июля 2010

Я думаю, что проблема в том, что 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));
0 голосов
/ 10 июля 2010

Я не смотрел на это очень долго, но первое, что я заметил, было то, что у вас есть одно открытое и три закрывающих.«Время» должно быть $ time?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...