8000 [HttpClient] Multiple form data fields with the same name · Issue #38258 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[HttpClient] Multiple form data fields with the same name #38258

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
HypeMC opened this issue Sep 21, 2020 · 4 comments · Fixed by #38323
Closed

[HttpClient] Multiple form data fields with the same name #38258

HypeMC opened this issue Sep 21, 2020 · 4 comments · Fixed by #38323

Comments

@HypeMC
Copy link
Contributor
HypeMC commented Sep 21, 2020

Description
This is related to #33488 but with form data instead of a query string. Basically I need to POST multiple values for the same filed. The FormDataPart automatically appends [key] to the filed's name, which in my case does not work as the api I'm using doesn't support this format. It would be great if there was a way to control this behavior and prevent the key from being appended to the name.

Example

$formFields = [
    'text' => [
        new TextPart('text1'),
        new TextPart('text2'),
    ],
];
$formData = new FormDataPart($formFields);

var_dump($formData->toString());

Actual:

Content-Type: multipart/form-data; boundary=YtAhd-DW\r\n\r\n--YtAhd-DW\r\n
Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: 8bit\r\n
Content-Disposition: form-data; name="text[0]"\r\n\r\n/text1\r\n--YtAhd-DW\r\n
Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: 8bit\r\n
Content-Disposition: form-data; name="text[1]"\r\n\r\n/text2\r\n--YtAhd-DW--\r\n

Expected:

Content-Type: multipart/form-data; boundary=YtAhd-DW\r\n\r\n--YtAhd-DW\r\n
Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: 8bit\r\n
Content-Disposition: form-data; name="text"\r\n\r\n/text1\r\n--YtAhd-DW\r\n
Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: 8bit\r\n
Content-Disposition: form-data; name="text"\r\n\r\n/text2\r\n--YtAhd-DW--\r\n
@stof
Copy link
Member
stof commented Sep 21, 2020

Given that multiple parameters with the same name text are not supported by PHP (related to the fact that PHP arrays cannot have duplicate keys), I don't see how this could be implemented in FormDataPart

@HypeMC
Copy link
Contributor Author
HypeMC commented Sep 21, 2020

@stof Well actually I was able to find a way to achieve this by extending the TextPart class:

class NamedTextPart extends TextPart
{
    private $isNameSet = false;

    public function __construct($name, $body, ?string $charset = 'utf-8', $subtype = 'plain', string $encoding = null)
    {
        parent::__construct($body, $charset, $subtype, $encoding);

        $this->setName($name);
    }

    public function setName($name)
    {
        if (!$this->isNameSet) {
            parent::setName($name);
            $this->isNameSet = true;
        }
    }
}

Even though it's not the prettiest solution, it seems to work.

Also, I don't see a reason why the FormDataPart couldn't be extended to add the key suffix optionally:

    private function prepareFields(array $fields): array
    {
        // ...

        $prepare = function ($item, $key, $root = null) use (&$values, &$prepare) {
            $fieldName = $root || $this->someNewFlag ? sprintf('%s[%s]', $root, $key) : $key;

            // ...

            $values[] = $this->preparePart($fieldName, $item);
        };

        // ...

        return $values;
    }

All in all it doesn't seem like implementing such a feature would be a problem.

@nicolas-grekas
Copy link
Member

Could you please send a PR so that we can discuss the proposal on actual code ?

@HypeMC
Copy link
Contributor Author
HypeMC commented Sep 22, 2020

Will do in the following few days 😄

@symfony symfony deleted a comment from nicolas-grekas Sep 29, 2020
@fabpot fabpot closed this as completed Sep 29, 2020
fabpot added a commit that referenced this issue Oct 2, 2020
…DataPart (HypeMC)

This PR was merged into the 5.2-dev branch.

Discussion
----------

[Mime] Allow multiple parts with the same name in FormDataPart

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #38258
| License       | MIT
| Doc PR        | -

Added the possibility to choose whether multiple parts with the same name should be suffixed or not:

```php
$f1 = new FormDataPart([
    'foo' => [
        'one',
        'two',
    ],
]);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=6rqazwiG

--6rqazwiG
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[0]"

one
--6rqazwiG
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[1]"

two
--6rqazwiG--
```

```php
$f1 = new FormDataPart([
    ['foo' => 'one'],
    ['foo' => 'two'],
]);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=xxW9dGzq

--xxW9dGzq
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo"

one
--xxW9dGzq
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo"

two
--xxW9dGzq--
```

Only applies to numeric keys:

```php
$f1 = new FormDataPart([
    'foo' => [
        'a' => 'one',
        'b' => 'two',
    ],
], true);

var_dump($f1->toString());
```

```
Content-Type: multipart/form-data; boundary=W6qkqgrD

--W6qkqgrD
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[a]"

one
--W6qkqgrD
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Disposition: form-data; name="foo[b]"

two
--W6qkqgrD--
```

Commits
-------

1f7f2c6 Allow multiple parts with the same name in FormDataPart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
0