I am using Zend_Http_Client to POST a set of data to my server running PHP. However, the server is expecting data in the form myField[]
, i.e. I have a set of check boxes and the user can check more than one. My current code is:
foreach ($myValues as $value) {
$this->client->setParameterPost('myField[]', $value);
}
However, it seems that Zend_Http_Client is simply overwriting myField[]
with the new value each time it goes through the loop. How can I add multiple POST fields of the same name using Zend_Http_Client?
UPDATE
I have actually figured out a way to do this, by hacking the Zend_Http_Client code itself. However this is not ideal. Here's how I did it:
First, I simply added the values to the POST fields like this:
$myValues = array(0,1,2);
$this->client->setParameterPost('myField', $myValues);
In the function _prepareBody()
, Zend_Http_Client builds the POST data with the following code:
$body = http_build_query($this->paramsPost, '', '&');
If you look at the POST data that it builds, it looks like this:
myField[0]=0&myField[1]=1&myField[2]=2
Of course, it is url-encoded, so it looks like this:
myField%5B0%5D=0&myField%5B1%5D=1&myField%5B2%D=2
So, I just added a preg_replace
to make [0] -> [], [1] -> [], etc:
$body = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $body);
I'd rather just use Zend_Http_Client without making changes to the library code, but this works for now. I'd be very grateful for any suggestions on how to do it without hacking the libraries.
The simplest approach may be just to set the raw post body yourself:
$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
If you have other variables to send in the postdata, you'll probably want to subclass Zend_Http_Client and override the implementation of _prepareBody()
as follows.
This modification aims to remain compatible with future updates, and as such, calls the parent method unless POST params are set, and the form is not multipart (a file upload):
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();
}
}
Usage
$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));