Мне нужно преобразовать следующую функцию 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));
Но я получаю следующую ошибку: Warning: pack () [function.pack]: Тип C: слишком мало аргументов в D: \ wamp \ www \ test.php в строке 8
Какие-либо предложения? Большое спасибо.
Проблема в том, что код передает 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()
в этом случае, когда вместо этого можно использовать preg_split()
. Регулярные выражения следует использовать только тогда, когда это строго необходимо, потому что функции регулярного выражения медленнее по сравнению с другими строковыми функциями.
Из документации PHP для pack () .
Упаковать заданные аргументы в двоичную строку в соответствии с форматом.
Идея этой функции была взята из Perl, и все коды форматирования работают так же, как и в Perl. Однако есть некоторые коды форматирования, которые отсутствуют, такие как код формата «u» Perl.
Разумеется, он должен работать так же, как есть? Возможно, вам придется переименовать некоторые переменные
Иногда утверждения об ошибках означают что-то заслуживающее рассмотрения. Слишком мало аргументов может означать необходимость пересмотреть каждый вход, используемый в инструкции пакета PHP, в соответствии с ожидаемым форматом.
Например, вы учли поле 'ar', используемое в инструкции perl pack? Из-за этого вы можете быть в результате упакованных данных одним полем.
Похоже, что у вас возникают проблемы с тем, что в 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');
Я думаю, что проблема в том, что 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));
Проблема в том, что php preg_split преобразует его в массив. Вам нужен символ unsigned, поэтому используйте
$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));
Дайте знать, как это происходит.
Мое первое предложение – внимательно прочитать документацию. Эта проблема имеет мало общего с perl и многое зависит от понимания того, что ожидает функция. Мое второе предложение состоит в том, чтобы привыкнуть немного нервничать всякий раз, когда вы копируете код. Нервное достаточно, чтобы уделять дополнительное внимание коду, документации и т. Д. По крайней мере, когда клиент / босс / кто-нибудь спрашивает вас, что делает этот бит скопированного кода, у вас должен быть хороший ответ.
Первый параметр для pack () – это строка формата. Это определяет, как он форматирует параметры при создании вывода.
Из документации для pack ():
Строка формата состоит из кодов формата, за которыми следует необязательный аргумент ретранслятора. Аргумент ретранслятора может быть либо целым, либо * для повторения в конце входных данных. Для 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.
Я не смотрел на это очень долго, но первое, что я заметил, это то, что у вас есть один открытый парик и три закрытия. Предполагается, что «время» составляет $ time?