dentro - php curl post json
¿POST una cadena de archivo usando cURL en PHP? (2)
Me preguntaba si es posible publicar un archivo, junto con otros datos del formulario, cuando el archivo es solo una cadena.
Sé que puede publicar un archivo que ya está en el sistema de archivos al ponerle un prefijo "@".
Sin embargo, me gustaría omitir la creación de un archivo temporal y enviar solo el archivo como una cadena, pero no estoy seguro de cómo construir la solicitud utilizando cURL en PHP.
Aclamaciones
$postFields = array(
''otherFields'' => ''Yes''
,''filename'' => ''my_file.csv''
,''data'' => ''comma seperated content''
);
$options = array(
CURLOPT_RETURNTRANSFER => true
,CURLOPT_SSL_VERIFYPEER => false
,CURLOPT_SSL_VERIFYHOST => 1
,CURLOPT_POSTFIELDS => $postFields
,CURLOPT_HTTPHEADER => array(
''Content-type: multipart/form-data''
)
);
Debería ser posible: aquí hay un formulario, publicado a través de un navegador (campos irrelevantes omitidos):
POST http://host.example.com/somewhere HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7da16b2e4026c
Content-Length: 105732
-----------------------------7da16b2e4026c
Content-Disposition: form-data; name="NewFile"; filename="test.jpg"
Content-Type: image/jpeg
(...raw JPEG data here...)
-----------------------------7da16b2e4026c
Content-Disposition: form-data; name="otherformfield"
content of otherformfield is this text
-----------------------------7da16b2e4026c--
Entonces, si construimos el cuerpo POST nosotros mismos y establecemos un encabezado extra o dos, deberíamos poder simular esto:
// form field separator
$delimiter = ''-------------'' . uniqid();
// file upload fields: name => array(type=>''mime/type'',content=>''raw data'')
$fileFields = array(
''file1'' => array(
''type'' => ''text/plain'',
''content'' => ''...your raw file content goes here...''
), /* ... */
);
// all other fields (not file upload): name => value
$postFields = array(
''otherformfield'' => ''content of otherformfield is this text'',
/* ... */
);
$data = '''';
// populate normal fields first (simpler)
foreach ($postFields as $name => $content) {
$data .= "--" . $delimiter . "/r/n";
$data .= ''Content-Disposition: form-data; name="'' . $name . ''"'';
// note: double endline
$data .= "/r/n/r/n";
}
// populate file fields
foreach ($fileFields as $name => $file) {
$data .= "--" . $delimiter . "/r/n";
// "filename" attribute is not essential; server-side scripts may use it
$data .= ''Content-Disposition: form-data; name="'' . $name . ''";'' .
'' filename="'' . $name . ''"'' . "/r/n";
// this is, again, informative only; good practice to include though
$data .= ''Content-Type: '' . $file[''type''] . "/r/n";
// this endline must be here to indicate end of headers
$data .= "/r/n";
// the file itself (note: there''s no encoding of any kind)
$data .= $file[''content''] . "/r/n";
}
// last delimiter
$data .= "--" . $delimiter . "--/r/n";
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_HTTPHEADER , array(
''Content-Type: multipart/form-data; boundary='' . $delimiter,
''Content-Length: '' . strlen($data)));
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
curl_exec($handle);
De esta manera, estamos haciendo todo el trabajo pesado nosotros mismos, y confiando en cURL para no arruinarlo.
php tiene acceso a una ubicación temporal "php: // memory", lo que realmente hace que lo que intentas hacer sea bastante fácil.
$fh = fopen(''php://memory'',''rw'');
fwrite( $fh, $content);
rewind($fh);
$options = array(
CURLOPT_RETURNTRANSFER => true
,CURLOPT_SSL_VERIFYPEER => false
,CURLOPT_SSL_VERIFYHOST => 1
,CURLOPT_HTTPHEADER => array(
''Content-type: multipart/form-data''
)
,CURLOPT_INFILE => $fh
,CURLOPT_INFILESIZE => strlen($content)
);