Как эмулировать POSTing несколько полей формы флажка myField [] с Zend_Http_Client? - PullRequest
2 голосов
/ 13 сентября 2011

Я использую Zend_Http_Client для отправки набора данных на мой сервер с PHP. Однако сервер ожидает данные в виде myField[], т. Е. У меня есть набор флажков, и пользователь может установить более одного. Мой текущий код:

   foreach ($myValues as $value) {
    $this->client->setParameterPost('myField[]', $value);
   }

Однако, похоже, что Zend_Http_Client просто перезаписывает myField[] новым значением каждый раз, когда проходит цикл. Как добавить несколько полей POST для с одинаковым именем с помощью Zend_Http_Client?


UPDATE

Я действительно нашел способ сделать это, взломав сам код Zend_Http_Client. Однако это не идеально. Вот как я это сделал:

Сначала я просто добавил значения в поля POST следующим образом:

$myValues = array(0,1,2);
$this->client->setParameterPost('myField', $myValues);

В функции _prepareBody() Zend_Http_Client создает данные POST со следующим кодом:

  $body = http_build_query($this->paramsPost, '', '&');

Если вы посмотрите на данные POST, которые он создает, он будет выглядеть так:

myField[0]=0&myField[1]=1&myField[2]=2

Конечно, он закодирован по URL, поэтому выглядит так:

myField%5B0%5D=0&myField%5B1%5D=1&myField%5B2%D=2

Итак, я просто добавил preg_replace, чтобы сделать [0] -> [], [1] -> [] и т. Д .:

$body = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $body);

Я бы предпочел просто использовать Zend_Http_Client без внесения изменений в код библиотеки, но пока это работает. Буду очень признателен за любые предложения о том, как это сделать без взлома библиотек.

1 Ответ

3 голосов
/ 13 сентября 2011

Самый простой подход может состоять в том, чтобы просто установить необработанное тело сообщения:

$values = array(
    0,
    1,
    2,
);

$key = 'myField';
$rawData = '';
foreach ($values as $value) {
    if ($rawData !== '') {
        $rawData .= '&';
    }
    $rawData .= $key . '%5B%5D=' . $value;
}

$client = new Zend_Http_Client();
$client->setRawData($rawData);
$client->setUri('http://www.davidcaunt.co.uk/');
$client->request(Zend_Http_Client::POST);

$request = $client->getLastRequest();

//Zend_Debug::dump($request);
Zend_Debug::dump(urldecode($request));

PostData

MyField [] = 0 & MyField [] = 1 & MyField [] = 2

Если у вас есть другие переменные для отправки в postdata, вы, вероятно, захотите создать подкласс Zend_Http_Client и переопределить реализацию _prepareBody() следующим образом.

Это изменение направлено на то, чтобы оставаться совместимым с будущими обновлениями, и поэтому вызывает родительский метод, если не заданы параметры POST, а форма не является составной (загрузка файла):

class My_Http_Client extends Zend_Http_Client
{

    function _prepareBody() 
    {
        if (count($this->paramsPost) > 0 && $this->enctype == self::ENC_URLENCODED) {
            $this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED);

            $body = '';
            foreach ($this->paramsPost as $key => $value) {

                if (is_array($value)) {
                    foreach ($value as $v) {
                        $body .= $key . '%5B%5D=' . $v . '&';
                    }
                } else {
                    $body .= $key . '=' . $value . '&';
                }               
            }

            return rtrim($body, '&');
        }

        return parent::_prepareBody();
    }
}

Использование

$client = new My_Http_Client();
$client->setParameterPost('name', 'John');
$client->setParameterPost('myField', array(0,1,2));
$client->setUri('http://www.davidcaunt.co.uk/');
$client->request(Zend_Http_Client::POST);

$request = $client->getLastRequest();

Zend_Debug::dump(urldecode($request));
...