2010-07-10 1 views
-1

Мне нужно преобразовать следующую PERL функцию PHP:Преобразование кода 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

Любые предложения? Большое спасибо.

ответ

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

+0

Спасибо, он отлично работал :) – Slim

6

Из документации PHP для 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.

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

+0

+1 для RTFM упражнения :) –

+1

@George: Мог бы также попытаться помочь в любом случае, хотя. – icktoofay

+2

@icktoofay «Дайте человеку рыбу, накормите его на день ...» –

-1

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

+0

http://perldoc.perl.org/functions/time.html – daxim

+0

Время не переменная – Slim

0

Я думаю, что проблема в том, что 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

Спасибо за ваше предложение. – Slim

0

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

и, как говорили другие плакаты, вы можете использовать explode вместо preg_split, если вы не ожидаете ничего, кроме IP. – pinaki

1

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

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

0

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

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

Из documentation для пакета():

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.

Таким образом, проблема заключается в том, что ваша строка формат не подходит для передаваемых аргументов пакет(). Теперь имейте в виду, что я должен угадать соответствующую строку формата для ваших нужд. Вы должны прочитать документацию и определить правильную строку формата.

следующие работы просто отлично:

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

Это не работает «отлично», он ставит полный мусорный символ, где должен быть IP-адрес. Как насчет упаковки 'inet_pton ($ addr)' с 'a4' или' ip2long ($ addr) 'с' N'? – hobbs

+0

@hobbs Как я уже отмечал, я понятия не имею, как он хочет, чтобы формат был отформатирован. Также обратите внимание, что вывод представляет собой строку ** BINARY **. «В этом контексте термины двоичная строка и строка байтов используются для указания строк, в которых сохраненные данные не обязательно (обязательно) представляют текст». http://en.wikipedia.org/wiki/String_%28computer_science%29 –

+0

Я понимаю, что вы должны угадать. Но угадать, что исходный формат (из рабочего кода) неправильный и что он имеет смысл представлять IP-адрес одним байтом, вероятно, не очень * хорошо * угадывает; предполагая, что исходный формат правильный и что он предназначен для представления IP-адреса каноническим способом (4 байта в сетевом порядке). Трудность, похоже, исходит из того факта, что perl выравнивает список в списке параметров, а PHP - нет.Я понятия не имею, о том, что ваш «** BINARY ** string» должен сказать нам, что мы еще этого не знаем. – hobbs

1

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