Skip to content

Commit 010cc48

Browse files
committed
bug #34032 [Mime] Fixing multidimensional array structure with FormDataPart (jvahldick)
This PR was merged into the 4.4 branch. Discussion ---------- [Mime] Fixing multidimensional array structure with FormDataPart | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #33063 #34031 | License | MIT | Doc PR | - The issue is pretty much described on #34031 The current structure of the raw body build on FormDataPart is not well recognized by the server. It considers all the fields as a root type, when actually it is possible to send arrays by html forms. Lets the following structure on the html ```html <input type="text" name="names[]" value="John" /> <input type="text" name="names[]" value="Doe" /> ``` It creates the following raw body: ``` ----------------------------466490401959219490193856 Content-Disposition: form-data; name="names[]" John ----------------------------466490401959219490193856 Content-Disposition: form-data; name="names[]" Doe ----------------------------466490401959219490193856-- ``` Meanwhile, the FormDataPart on Mime component generates the following body: ``` --_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_ Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-Disposition: form-data John --_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_ Content-Type: text/plain; charset=utf-8; name=1 Content-Transfer-Encoding: 8bit Content-Disposition: form-data; name=1 Doe --_=_symfony_1571410799_b7846b3b4e86d821cdec4379e62b4068_=_-- ``` For more complex structures, the $_POST doesn't even recognize properly the field names and values. Commits ------- ca630e5351 Changing the multipart form-data behavior to use the form name as an array, which makes it recognizable as an array by PHP on the $_POST globals once it is coming from the HttpClient component
2 parents 89da7b6 + 51d5b0e commit 010cc48

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

Part/Multipart/FormDataPart.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,20 @@ public function getParts(): array
5656
private function prepareFields(array $fields): array
5757
{
5858
$values = [];
59-
array_walk_recursive($fields, function ($item, $key) use (&$values) {
60-
if (!\is_array($item)) {
61-
$values[] = $this->preparePart($key, $item);
59+
60+
$prepare = function ($item, $key, $root = null) use (&$values, &$prepare) {
61+
$fieldName = $root ? sprintf('%s[%s]', $root, $key) : $key;
62+
63+
if (\is_array($item)) {
64+
array_walk($item, $prepare, $fieldName);
65+
66+
return;
6267
}
63-
});
68+
69+
$values[] = $this->preparePart($fieldName, $item);
70+
};
71+
72+
array_walk($fields, $prepare);
6473

6574
return $values;
6675
}

Tests/Part/Multipart/FormDataPartTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,34 @@ public function testConstructor()
4747
$this->assertEquals([$t, $b, $c], $f->getParts());
4848
}
4949

50+
public function testNestedArrayParts()
51+
{
52+
$p1 = new TextPart('content', 'utf-8', 'plain', '8bit');
53+
$f = new FormDataPart([
54+
'foo' => clone $p1,
55+
'bar' => [
56+
'baz' => [
57+
clone $p1,
58+
'qux' => clone $p1,
59+
],
60+
],
61+
]);
62+
63+
$this->assertEquals('multipart', $f->getMediaType());
64+
$this->assertEquals('form-data', $f->getMediaSubtype());
65+
66+
$p1->setName('foo');
67+
$p1->setDisposition('form-data');
68+
69+
$p2 = clone $p1;
70+
$p2->setName('bar[baz][0]');
71+
72+
$p3 = clone $p1;
73+
$p3->setName('bar[baz][qux]');
74+
75+
$this->assertEquals([$p1, $p2, $p3], $f->getParts());
76+
}
77+
5078
public function testToString()
5179
{
5280
$p = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');

0 commit comments

Comments
 (0)