22 require_once
'HTTP/Request2/Exception.php';
50 private $_params = array();
56 private $_uploads = array();
62 private $_headerParam =
"--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
68 private $_headerUpload =
"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
78 private $_pos = array(0, 0);
90 public function __construct(array $params, array $uploads, $useBrackets =
true)
92 $this->_params = self::_flattenArray(
'', $params, $useBrackets);
93 foreach ($uploads as $fieldName => $f) {
94 if (!is_array($f[
'fp'])) {
95 $this->_uploads[] = $f + array(
'name' => $fieldName);
97 for ($i = 0; $i < count($f[
'fp']); $i++) {
99 'name' => ($useBrackets? $fieldName .
'[' . $i .
']': $fieldName)
101 foreach (array(
'fp',
'filename',
'size',
'type') as $key) {
102 $upload[$key] = $f[$key][$i];
104 $this->_uploads[] = $upload;
118 $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
119 $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
120 $length = $boundaryLength + 6;
121 foreach ($this->_params as $p) {
122 $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
124 foreach ($this->_uploads as $u) {
125 $length += $headerUploadLength + strlen($u[
'name']) + strlen($u[
'type']) +
126 strlen($u[
'filename']) + $u[
'size'] + 2;
138 if (empty($this->_boundary)) {
139 $this->_boundary =
'--' . md5(
'PEAR-HTTP_Request2-' . microtime());
141 return $this->_boundary;
156 $paramCount = count($this->_params);
157 $uploadCount = count($this->_uploads);
158 while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
159 $oldLength = $length;
160 if ($this->_pos[0] < $paramCount) {
162 $this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
163 ) . $this->_params[$this->_pos[0]][1] .
"\r\n";
164 $ret .= substr($param, $this->_pos[1], $length);
165 $length -= min(strlen($param) - $this->_pos[1], $length);
167 } elseif ($this->_pos[0] < $paramCount + $uploadCount) {
168 $pos = $this->_pos[0] - $paramCount;
170 $this->_headerUpload, $boundary, $this->_uploads[$pos][
'name'],
171 $this->_uploads[$pos][
'filename'], $this->_uploads[$pos][
'type']
173 if ($this->_pos[1] < strlen($header)) {
174 $ret .= substr($header, $this->_pos[1], $length);
175 $length -= min(strlen($header) - $this->_pos[1], $length);
177 $filePos = max(0, $this->_pos[1] - strlen($header));
178 if ($filePos < $this->_uploads[$pos][
'size']) {
179 while ($length > 0 && !feof($this->_uploads[$pos][
'fp'])) {
180 if (
false === ($chunk = fread($this->_uploads[$pos][
'fp'], $length))) {
186 $length -= strlen($chunk);
190 $start = $this->_pos[1] + ($oldLength - $length) -
191 strlen($header) - $this->_uploads[$pos][
'size'];
192 $ret .= substr(
"\r\n", $start, $length);
193 $length -= min(2 - $start, $length);
197 $closing =
'--' . $boundary .
"--\r\n";
198 $ret .= substr($closing, $this->_pos[1], $length);
199 $length -= min(strlen($closing) - $this->_pos[1], $length);
202 $this->_pos = array($this->_pos[0] + 1, 0);
204 $this->_pos[1] += $oldLength;
217 $this->_pos = array(0, 0);
218 foreach ($this->_uploads as $u) {
248 private static function _flattenArray($name, $values, $useBrackets)
250 if (!is_array($values)) {
251 return array(array($name, $values));
254 foreach ($values as $k => $v) {
257 } elseif ($useBrackets) {
258 $newName = $name .
'[' . $k .
']';
262 $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
__construct(array $params, array $uploads, $useBrackets=true)