2013-03-19 8 views
5

c'è un modo di fareCome RAW POST enorme file XML con l'arricciatura - PHP

curl -X POST -H "Content-Type:application/xml" --data @myfile.xml http://example.com 

ma direttamente in PHP?

CURLOPT_PUT/CURLOPT_UPLOAD così come file_get_contents così come exec

non sono una soluzione in quanto deve essere post e il file è enorme, quindi deve essere in streaming.

Qualche idea?

+0

Per inviare un file su un server, provate questo: http://stackoverflow.com/questions/4223977/send-file-via-curl-from-form-post-in-php – silkfire

risposta

1

Curl supporta post, in modo credo che siete alla ricerca di qualcosa di simile: Posting or Uploading Files Using Curl With PHP

// URL on which we have to post data 
$url = "http://localhost/tutorials/post_action.php"; 
// Any other field you might want to catch 
$post_data['name'] = "khan"; 
// File you want to upload/post 
$post_data['file'] = "@c:/logs.log"; 

// Initialize cURL 
$ch = curl_init(); 
// Set URL on which you want to post the Form and/or data 
curl_setopt($ch, CURLOPT_URL, $url); 
// Data+Files to be posted 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 
// Pass TRUE or 1 if you want to wait for and catch the response against the request made 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
// For Debug mode; shows up any error encountered during the operation 
curl_setopt($ch, CURLOPT_VERBOSE, 1); 
// Execute the request 
$response = curl_exec($ch); 

// Just for debug: to see response 
echo $response; 

(Tutto il merito per il codice all'autore collegato originale).

Per quanto riguarda "enorme", ti consigliamo di essere più specifico - kb, mb, gb, tb? I problemi aggiuntivi saranno correlati a quanto tempo uno script PHP può rimanere attivo senza essere terminato automaticamente, utilizzo della memoria di script (che potrebbe richiedere che le cose vengano gestite in blocchi invece di caricare l'intero file), ecc.

MODIFICA: Ah per il post RAW penso che ne avrai quindi bisogno: Raw POST using Curl in PHP

+0

che è non un POST RAW con Content-Type: application/xml, è un Content-Type: multipart/form-data. Con enorme intendo che non puoi caricare in memoria – Marcin

+0

Ah, beh se non riesci a caricarlo in memoria, allora capisco cosa vuoi dire, nessuno di questi funzionerà come curl_exec() aspetterà fino a quando non avrai finito di inviare - by in quale momento lo script si sarà bloccato. – BrianHall

+0

non se è possibile eseguire lo streaming, come con il post generico e @ – Marcin

12

Ho avuto un problema simile nel tentativo di inviare enormi file di ingestione alla bulk API di elasticsearch da PHP, fino a quando ho capito che l'endpoint dell'APP bulk accettava le richieste PUT. In ogni caso, questo codice esegue le richieste POST con file di grandi dimensioni:

$curl = curl_init(); 
curl_setopt($curl, CURLOPT_PUT, 1); 
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($tmpFile)); 
curl_setopt($curl, CURLOPT_INFILE, ($in=fopen($tmpFile, 'r'))); 
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); 
curl_setopt($curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json' ]); 
curl_setopt($curl, CURLOPT_URL, $url); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
$result = curl_exec($curl); 
curl_close($curl); 
fclose($in); 

Qui, $tmpFile è il percorso completo del file contenente il corpo della richiesta.

NOTA: La parte importante è la creazione di CURLOPT_CUSTOMREQUEST-'POST' anche se CURLOPT_PUT è impostato.

Dovresti adattare l'intestazione Content-Type: a qualsiasi cosa il server si aspetti.

Utilizzando tcpdump, ho potuto confermare il metodo di richiesta di essere POST:

POST /my_index/_bulk HTTP/1.1 
Host: 127.0.0.1:9200 
Accept: */* 
Content-Type: application/json 
Content-Length: 167401 
Expect: 100-continue 

[...snip...] 

sto utilizzando pacchetti libcurl3 (versione 7.35.0-1ubuntu2.5) e PHP5-ricciolo (versione 5.5.9+ dfsg-1ubuntu4.11) su Ubuntu 14.04.

+1

+1 per la verifica con tcpdump. Impostando le opzioni e confidando che fosse tutto ciò che dovevo fare (ad esempio, le opzioni non sono mai in conflitto, l'ordine delle opzioni è irrilevante, * et cetera *) mi ha morso più di una volta. – LSerni

+0

Bene, sono un po 'a disagio con le opzioni in conflitto, ecco perché ho elencato le versioni del pacchetto. Nel mio caso "CURLOPT_CUSTOMREQUEST" sovrascrive altre opzioni, ma non sono sicuro che funzioni * come previsto * ed è una soluzione duratura. – Shadocko

+0

Mille grazie! Sto postando/mettendo i dati di file grezzi direttamente su un'API, e mentre il PUT è stato facile usando CURLOPT_INFILE non sono riuscito a capire come far funzionare POST poiché utilizza sempre dati di moduli multipart. Questa era esattamente la parte che mancavo: basta impostare la richiesta personalizzata su POST. – phansen