2009-09-01 17 views
28

Secondo php manual né php: // input n. $HTTP_RAW_POST_DATA funziona con multipart/form-data richieste POST.Ottieni dati post-raw

"php: // input consente di leggere i dati POST non elaborati, un'alternativa meno intensiva della memoria a $HTTP_RAW_POST_DATA e non richiede alcuna direttiva speciale php.ini. Php: // input non è disponibile con enctype="multipart/form-data"."

Come posso ottenere i dati grezzi per i moduli multipart/form-data?

+0

Se è per il bene di contare byte, non puoi combinare il conteggio di $ HTTP_RAW_POST_DATA byte con il numero di byte di qualsiasi $ _FILES? – karim79

+0

@ karim79, perché non lo è. – Pacerier

risposta

34

Risposta diretta: non puoi farlo. PHP insiste nel parsing stesso, ogni volta che vede il Content-Type multipart/form-data. I dati grezzi non saranno disponibili per te. Purtroppo. Ma puoi hackerarci intorno.

Ho riscontrato un problema simile, un partner inviava dati formattati in modo errato come multipart/form-data, PHP non poteva analizzarlo e non lo stava distribuendo in modo da poterlo analizzare personalmente.

La soluzione? Ho aggiunto questo al mio conf apache:

<Location "/backend/XXX.php"> 
    SetEnvIf Content-Type ^(multipart/form-data)(.*) NEW_CONTENT_TYPE=multipart/form-data-alternate$2 OLD_CONTENT_TYPE=$1$2 
    RequestHeader set Content-Type %{NEW_CONTENT_TYPE}e env=NEW_CONTENT_TYPE 
</Location> 

Questo cambierà il Content-Type della richiesta in arrivo per XXX.php da multipart/form-data per multipart/form-data-alternativo, che è sufficiente per bloccare PHP dal tentativo di analizzarlo

Dopo questo puoi finalmente leggere l'intero file raw da php: // input e analizzarlo da solo.

È brutto, ma non ho trovato una soluzione migliore o di fatto qualsiasi altra soluzione, a meno che non chieda al partner di sistemare la propria parte.

NB! Quando fai ciò che ho descritto qui, $ _FILES sarà vuoto.

+0

Se sostituisco l'intestazione Content-type in questo modo, torno alla fonte php nel mio browser. Sembra che il motore php non elabori questa richiesta. Qual è il trucco? Ho usato diversi sostituti di intestazione, nessuno dei quali funzionava. –

+0

Sembra che sia ** possibile ** farlo con ['enable_post_data_reading'] (http://stackoverflow.com/a/19710850/632951). – Pacerier

+0

@Pacerier - possibile, la mia risposta è stata scritta prima di php 5.4 –

5

Non l'ho implementato completamente, ma sembra che dovrebbe funzionare. In Apache conf:

SetEnvIf Content-Type ^(multipart/form-data)(.*) MULTIPART_CTYPE=$1$2 
RequestHeader set Content-Type application/x-httpd-php env=MULTIPART_CTYPE 
RequestHeader set X-Real-Content-Type %{MULTIPART_CTYPE}e env=MULTIPART_CTYPE 

Impostazione del Content-Type per application/x-httpd-php sembra risolvere il problema originale di PHP analisi del corpo, e il problema Norbert Farkas riportato: "Apache restituisce il codice sorgente PHP". Il corpo è quindi disponibile su php://input e il tipo di contenuto reale nell'intestazione X-Real-Content-Type. (L'intestazione potrebbe non essere necessaria per te: la variabile MULTIPART_CTYPE non sembra essere visualizzata nel mio $_ENV, ma la nuova intestazione ha fatto.) Tutte le altre richieste dovrebbero essere gestite come al solito.

Grazie a Anti Veeranna per la maggior parte! :)

MODIFICA: P.S. Ovviamente è specifico per Apache, ma in alcune delle altre configurazioni di PHP ci potrebbero essere dei modi più semplici.

9

È possibile impostare enable_post_data_reading = Off e PHP non intercetterà i dati multipart/form-data.

Richiede: PHP 5.4

+1

Interessante. Soprattutto quando il manuale PHP insiste altrove, è impossibile ottenere il corpo grezzo in caso di 'multipart/form-data'. – Anshul

+0

@Anshul, il manuale lo dice ancora? Non esiste una versione coerente del manuale. Alcune pagine sono la versione X mentre altre sono nella versione Z. – Pacerier

+0

@Pacerier, ritengo ancora che non sia possibile ottenere il grezzo multipart/form-data. Tutti i seguenti collegamenti suggeriscono che: http://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data http://php.net/manual/en /ini.core.php#ini.enable-post-data-reading http://php.net/manual/en/wrappers.php.php http://php.net/manual/en/reserved.variables .httprawpostdata.php – Anshul

Problemi correlati