[PHP] GuzzleHTTP multipart multidimensional name

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
Hee!

Simpele versie
Ik heb een multidimensionale array en die wil ik met multipart met Guzzle versturen, enig idee? :D

Long story
Op dit moment gebruik ik GuzzleHTTP in laravel om een api request te maken om data te posten. (http://docs.guzzlephp.org/en/latest/index.html)

Na veel zwoegen en google doorspitten krijg ik maar niet de juiste methode gevonden om een multidimensionale array te sturen met Guzzle. Hiermee bedoel ik op de volgende manier, ik stuur een file mee dus ik ben verplicht volgens de documentatie om multipart te gebruiken.

De volgende structuur wil Guzzle hebben om nested variables door te sturen als een array.

code:
1
2
3
4
5
6
7
8
9
10
'multipart' => [
    [
        'name' => 'firstname',
        'contents' => 'Danny'
    ],
    [
        'name' => 'phone[0][phone]',
        'contents' => '0612345678'
    ]
]


Echter als je natuurlijk je velden ophaalt krijg je een multidimensionale array natuurlijk zoals onderstaand :+

code:
1
2
3
4
5
6
7
8
[
    [firstname] => 'Danny',
    [phone] => [
        [0] => [
            [phone] => 0612345678
        ]
    ]
]


Mijn vraag is voornamelijk hoe krijg ik het zo makkelijk mogelijk voor elkaar dat Guzzle mijn multidimensionale array accepteert en het doorstuurt naar behoren zonder rare hacks toe te hoeven passen. Dit lijkt me toch wel te doen naar mijn idee, ben niet de enige die Guzzle gebruikt met multidimensionale arrays al doet google mij dat bijna wel geloven.

Heb zelf ook een aantal topics gevonden en natuurlijk vanalles geprobeerd zoals het volgende.

http://stackoverflow.com/...oad-files-with-array-data
- Deze zegt alleen hoe het moet, dat had ik al door alleen daar staat niet bij hoe ik dit voor elkaar kan krijgen

http://docs.guzzlephp.org...light=multipart#multipart
- Officiele Guzzle documentatie toont geen methode om multidimensionale arrays door te sturen, echter wel dat de contents variable in multipart het volgende accepteert;

contents: (StreamInterface/resource/string, required) The data to use in the form element.

Helaas ben ik dan nog niet tot de oplossing gekomen en sta ik nog voor een raadsel hoe ik dit voor elkaar moet krijgen.

Acties:
  • 0 Henk 'm!

  • Fraekje
  • Registratie: April 2004
  • Laatst online: 19-08-2024
Maak het je jezelf niet te moeilijk? Je zou gewoon de hele array zoals je wilt kunnen versturen als JSON?

Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
Fraekje schreef op woensdag 11 januari 2017 @ 09:16:
Maak het je jezelf niet te moeilijk? Je zou gewoon de hele array zoals je wilt kunnen versturen als JSON?
Dit had gekunnen als de array niet resource items bevatten. Er zit al een fopen() array item in en die kan je niet omzetten naar JSON dan crasht json_encode().

value
The value being encoded. Can be any type except a resource.

Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 09-10 15:13

TheNephilim

Wtfuzzle

Maar die API vereist dus dat je multipart-form-data stuurt? Geen JSON of gewoon (zoals al genoemd) een array in de body?

Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
TheNephilim schreef op woensdag 11 januari 2017 @ 10:00:
Maar die API vereist dus dat je multipart-form-data stuurt? Geen JSON of gewoon (zoals al genoemd) een array in de body?
Exact, de betreffende API verwacht multipart form data als er een file meegestuurd word. Dit is natuurlijk wel leuk maar handig is het niet maar ik kan de API kant niet wijzigen helaas. Het maakt het er niet makkelijker mee erg genoeg waardoor ik dus tegen dit probleem aan loop.

Ik weet dat Curl dit allemaal wel zou kunnen doormiddel van CurlFile en dergelijke alleen men roept altijd hard dat je beter Guzzle kan gebruiken dus dan wil ik daar graag naar kijken maar het lijkt erop dat het toch Curl wordt ;(

Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 09-10 15:13

TheNephilim

Wtfuzzle

Ja je zult toch iets als onderstaande moeten doen:

code:
1
2
3
4
5
6
7
8
9
10
'multipart' => [
    [
        'name' => 'firstname',
        'contents' => 'Danny'
    ],
    [
        'name' => 'phone[0][phone]',
        'contents' => '0612345678'
    ]
]


Dus je probleem is het converteren van je eigen array naar bovenstaande multipart-form-data format?

Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
Klopt helemaal, alleen mijn vraag is dan ook wel meer hoe ik de name op deze manier kan opbouwen. Dat krijg ik namelijk niet gevonden. Ik kan dit natuurlijk wel handmatig doen maar bij een grote applicatie is dit niet wenselijk meer natuurlijk.

Krijg zelf namelijk geen methode gemaakt die dit voor elkaar krijgt met de 'name' of een andere manier van multipart form data op te bouwen.

Acties:
  • 0 Henk 'm!

  • Fraekje
  • Registratie: April 2004
  • Laatst online: 19-08-2024
Ik begrijp niet precies wat je input is? Ik neem aan dat je het onderstaande wilt verzenden in een valid guzzle format?

code:
1
2
3
4
5
6
7
[ 
'name' => 'Danny',
'phone' => [
  '0612345678',
  '0612345679'
  ]
]


Zou je een voorbeeld van je input array en vervolgens je 'gewenste' output array kunnen geven?
Als ik het goed begrijp heeft de vraag geen betrekking op guzzle maar op het omzetten van arrays in een ander format :) ?

Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
De onderstaande data heb ik die doorgestuurd moet worden.

code:
1
2
3
4
5
6
7
[ 
'name' => 'Danny',
'phone' => [
  ['phone' => '0612345678',
  ['phone' => '0612345679'
  ]
]


Volgens Guzzle zou het op de volgende manier moeten.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
'multipart' => [
 [
   'name' => 'name',
   'contents' => 'Danny'
 ],
 [
   'name' => 'phone[0][phone]',
   'contents' => '0612345678'
 ],
 [
   'name' => 'phone[1][phone]',
   'contents' => '0612345679'
 ]
]


In principe gaat het niet geheel over Guzzle echter de manier om het te versturen naar hun wens kom ik wel op een probleem uit dat ik de data die Guzzle verwacht niet opgebouwd krijg en dus eventueel de vraag heb hoe dat eventueel kan of een andere manier moet gebruiken om het makkelijker te doen.

Acties:
  • 0 Henk 'm!

  • Fraekje
  • Registratie: April 2004
  • Laatst online: 19-08-2024
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$input = [
    'name' => 'Danny',
    'phone' => [
        ['phone' => '0612345678'],
        ['phone' => '0612345679']
    ]
];

function arrayToMultipart(array $array){
    $output = [];
    foreach($array as $key => $value){
        if(!is_array($value)){
            $output[] = ['name' => $key, 'contents' => $value];
            continue;
        }

        foreach($value as $multiKey => $multiValue){
            $multiName = $key . '[' .$multiKey . '][' . key($multiValue)  . ']';
            $output[] = ['name' => $multiName, 'contents' => reset($multiValue)];
        }
    }
    return $output;
}

$multipart = arrayToMultipart($input);
var_dump($multipart);


Vast niet de meest efficiënte of mooie manier, maar ik denk dat het doet wat je verwacht? Misschien kun je hiermee verder?

EDIT: Heb het in een functie gegoten :)

[ Voor 24% gewijzigd door Fraekje op 11-01-2017 14:14 ]


Acties:
  • 0 Henk 'm!

  • DannyBevers
  • Registratie: November 2009
  • Laatst online: 20:56
@Fraekje Dat is precies wat ik nodig had inderdaad! Het is jammer dat het zo in elkaar gebouwd moet worden maar weinig keuze. De functie werkte niet helemaal, omdat key() een value was en bij reset() ook waardoor die crasht. Vandaar een beetje omgebouwd naar dit voor degene die het nuttig vind.

Heel erg bedankt daarentegen! Heb het inmiddels werkend gekregen naar behoren!

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        $output = [];

        foreach($data as $key => $value){
            if(!is_array($value)){
                $output[] = ['name' => $key, 'contents' => $value];
                continue;
            }

            foreach($value as $multiKey => $multiValue){
                $multiName = $key . '[' .$multiKey . ']' . (is_array($multiValue) ? '[' . key($multiValue) . ']' : '' ) . '';
                $output[] = ['name' => $multiName, 'contents' => (is_array($multiValue) ? reset($multiValue) : $multiValue)];
            }
        }

        var_dump($output);
Pagina: 1