subir servidor para move_uploaded_file formulario ejemplo codigo archivos _put _files php file http put

servidor - subir archivos php mysql



Cómo recibir un archivo a través de HTTP PUT con PHP (5)

Aquí está la solución que encontré más útil.

$put = array(); parse_str(file_get_contents(''php://input''), $put);

$put será una matriz, tal como está acostumbrado a ver en $_POST , excepto que ahora puede seguir el verdadero protocolo REST HTTP.

Esto es algo que me ha estado molestando por un tiempo ... Estoy creando una API RESTful que tiene que recibir archivos en algunas ocasiones.

Cuando se utiliza HTTP POST , podemos leer data from $_POST y files from $_FILES .

Cuando se usa HTTP GET , podemos leer data from $_GET y files from $_FILES .

Sin embargo, cuando se usa HTTP PUT , AFAIK, la única forma de leer datos es usar el php://input stream .

Todo bien y bien, hasta que quiero enviar un archivo a través de HTTP PUT. Ahora el flujo de entrada php: // ya no funciona como se espera, ya que también tiene un archivo allí.

Así es como actualmente leo datos en una solicitud PUT:

(que funciona muy bien siempre que no haya archivos publicados)

$handle = fopen(''php://input'', ''r''); $rawData = ''''; while ($chunk = fread($handle, 1024)) { $rawData .= $chunk; } parse_str($rawData, $data);

Cuando luego salgo rawData, se muestra

-----ZENDHTTPCLIENT-44cf242ea3173cfa0b97f80c68608c4c Content-Disposition: form-data; name="image_01"; filename="lorem-ipsum.png" Content-Type: image/png; charset=binary �PNG ���...etc etc... ���, -----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380 Content-Disposition: form-data; name="testkey" testvalue -----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380 Content-Disposition: form-data; name="otherkey" othervalue

¿Alguien sabe cómo recibir correctamente los archivos a través de HTTP PUT, o cómo analizar archivos fuera de la secuencia de entrada php: //?

===== ACTUALIZACIÓN # 1 =====

He intentado solo el método anterior, realmente no tengo ni idea de lo que puedo hacer de otra manera.

No he recibido ningún error con este método, además de que no obtengo el resultado deseado de los datos y archivos publicados.

===== ACTUALIZACIÓN # 2 =====

Estoy enviando esta solicitud de prueba utilizando Zend_Http_Client, de la siguiente manera: (no he tenido ningún problema con Zend_Http_Client hasta ahora)

$client = new Zend_Http_Client(); $client->setConfig(array( ''strict'' => false, ''maxredirects'' => 0, ''timeout'' => 30) ); $client->setUri( ''http://...'' ); $client->setMethod(Zend_Http_Client::PUT); $client->setFileUpload( dirname(__FILE__) . ''/files/lorem-ipsum.png'', ''image_01''); $client->setParameterPost(array(''testkey'' => ''testvalue'', ''otherkey'' => ''othervalue''); $client->setHeaders(array( ''api_key'' => ''...'', ''identity'' => ''...'', ''credential'' => ''...'' ));

===== SOLUCIÓN =====

Resulta que hice algunas suposiciones erróneas, principalmente que HTTP PUT sería similar a HTTP POST. Como puede leer a continuación, DaveRandom me explicó que HTTP PUT no está destinado a transferir múltiples archivos en la misma solicitud.

Ahora he movido la transferencia de formdata del cuerpo a url querystring. El cuerpo ahora contiene el contenido de un solo archivo.

Para más información, lea la respuesta de DaveRandom. Es épico.


Los datos que muestra no representan un cuerpo de solicitud PUT válido (bueno, podría , pero lo dudo). Lo que muestra es un cuerpo de solicitud multipart/form-data : el tipo MIME utilizado al cargar archivos a través de HTTP POST a través de un formulario HTML.

Las solicitudes PUT deben complementar exactamente la respuesta a una solicitud GET: le envían el contenido del archivo en el cuerpo del mensaje y nada más.

Esencialmente, lo que digo es que no es su código para recibir el archivo que está mal, es el código que está haciendo la solicitud; el código del cliente es incorrecto, no el código que se muestra aquí (aunque la llamada parse_str() es un ejercicio sin sentido).

Si explica qué es el cliente (un navegador, un script en otro servidor, etc.), entonces puedo ayudarlo a continuar con esto. Tal como está, el método de solicitud apropiado para el cuerpo de la solicitud que usted representa es POST, no PUT.

Demos un paso atrás del problema y observemos el protocolo HTTP en general, específicamente el lado de la solicitud del cliente. Esperamos que esto le ayude a comprender cómo se supone que todo esto funciona. Primero, un poco de historia (si no estás interesado en esto, siéntete libre de saltarte esta sección).

Historia

HTTP fue diseñado originalmente como un mecanismo para recuperar documentos HTML de servidores remotos. Al principio, solo era compatible con el método GET, por lo que el cliente solicitaría un documento por su nombre y el servidor lo devolvería al cliente. La primera especificación pública para HTTP, etiquetada como HTTP 0.9, apareció en 1991, y si está interesado, puede leerla here .

La especificación HTTP 1.0 (formalizada en 1996 con RFC 1945 ) amplió considerablemente las capacidades del protocolo, agregando los métodos HEAD y POST. No era compatible con HTTP 0.9, debido a un cambio en el formato de la respuesta: se agregó un código de respuesta, así como la capacidad de incluir metadatos para el documento devuelto en forma de encabezados de formato MIME: datos de clave / valor pares HTTP 1.0 también abstrajo el protocolo de HTML, permitiendo la transferencia de archivos y datos en otros formatos.

HTTP 1.1, la forma del protocolo que se usa casi exclusivamente en la actualidad se basa en HTTP 1.0 y se diseñó para ser compatible con versiones anteriores de las implementaciones de HTTP 1.0. Se estandarizó en 1999 con RFC 2616 . Si usted es un desarrollador que trabaja con HTTP, conozca este documento: es su biblia. Comprenderlo completamente le dará una ventaja considerable sobre sus compañeros que no lo hacen.

Llegar al punto ya

HTTP funciona en una arquitectura de solicitud-respuesta: el cliente envía un mensaje de solicitud al servidor, el servidor devuelve un mensaje de respuesta al cliente.

Un mensaje de solicitud incluye un MÉTODO, un URI y, opcionalmente, un número de HEADERS. El MÉTODO de solicitud es a lo que se refiere esta pregunta, así que es lo que cubriré con mayor profundidad aquí, pero primero es importante comprender exactamente a qué nos referimos cuando hablamos de la URI de la solicitud.

El URI es la ubicación en el servidor del recurso que estamos solicitando. En general, esto consiste en un componente de ruta y, opcionalmente, una cadena de consulta . Hay circunstancias en las que otros componentes también pueden estar presentes, pero por razones de simplicidad, los ignoraremos por el momento.

Imaginemos que escribe http://server.domain.tld/path/to/document.ext?key=value en la barra de direcciones de su navegador. El navegador desmonta esta cadena y determina que necesita conectarse a un servidor HTTP en server.domain.tld , y solicita el documento en /path/to/document.ext?key=value .

La solicitud HTTP 1.1 generada se verá (como mínimo) así:

GET /path/to/document.ext?key=value HTTP/1.1 Host: server.domain.tld

La primera parte de la solicitud es la palabra GET , este es el MÉTODO de solicitud. La siguiente parte es la ruta al archivo que estamos solicitando, esta es la URI de solicitud. Al final de esta primera línea hay un identificador que indica la versión del protocolo en uso. En la siguiente línea puede ver un encabezado en formato MIME, llamado Host . HTTP 1.1 exige que el encabezado Host: se incluya con cada solicitud. Este es el único encabezado de que esto es cierto.

La solicitud de URI se divide en dos partes: ¿todo a la izquierda del signo de interrogación ? es la ruta , todo a la derecha de ella es la cadena de consulta .

Métodos de solicitud

RFC 2616 (HTTP / 1.1) define 8 métodos de solicitud .

OPTIONS

El método de OPCIONES rara vez se utiliza. Está pensado como un mecanismo para determinar qué tipo de funcionalidad admite el servidor antes de intentar consumir un servicio que el servidor puede proporcionar.

Desde el principio, el único lugar en el uso bastante común en el que puedo pensar dónde se usa esto es cuando abro documentos en la oficina de Microsoft directamente a través de HTTP desde Internet Explorer. Office enviará una solicitud de OPCIONES al servidor para determinar si admite el método PUT para el URI específico, y si lo hace, abrirá el documento de manera que permita al usuario guardar sus cambios en el documento directamente al servidor remoto. Esta funcionalidad está estrechamente integrada dentro de estas aplicaciones específicas de Microsoft.

GET

Este es, de lejos, el método más común en el uso diario. Cada vez que cargue un documento normal en su navegador web será una solicitud GET.

El método GET solicita que el servidor devuelva un documento específico. La única información que debe transmitirse al servidor es la información que el servidor necesita para determinar qué documento debe devolverse. Esto puede incluir información que el servidor puede usar para generar dinámicamente el documento, que se envía en forma de encabezados y / o cadena de consulta en el URI de la solicitud. Mientras estamos en el tema, las cookies se envían en los encabezados de solicitud.

HEAD

Este método es idéntico al método GET, con una diferencia: el servidor no devolverá el documento solicitado, si solo devolverá los encabezados que se incluirían en la respuesta. Esto es útil para determinar, por ejemplo, si un documento en particular existe sin tener que transferir y procesar todo el documento.

POST

Este es el segundo método más usado, y posiblemente el más complejo. Las solicitudes de método POST se utilizan casi exclusivamente para invocar algunas acciones en el servidor que pueden cambiar su estado.

Una solicitud POST, a diferencia de GET y HEAD, puede (y generalmente lo hace) incluir algunos datos en el cuerpo del mensaje de solicitud. Estos datos pueden estar en cualquier formato, pero generalmente es una cadena de consulta (en el mismo formato que aparecería en el URI de la solicitud) o un mensaje de varias partes que puede comunicar pares clave / valor junto con archivos adjuntos.

Muchos formularios HTML utilizan el método POST. Para cargar archivos desde un navegador, debe utilizar el método POST para su formulario.

El método POST es semánticamente incompatible con las API RESTful porque no es idempotent . Es decir, una segunda solicitud POST idéntica puede dar lugar a un cambio adicional en el estado del servidor. Esto contradice la restricción "sin estado" de REST.

PUT

Esto complementa directamente a GET. Cuando una solicitud GET indica que el servidor debe devolver el documento en la ubicación especificada por el URI de la solicitud en el cuerpo de la respuesta, el método PUT indica que el servidor debe almacenar los datos en el cuerpo de la solicitud en la ubicación especificada por el URI de la solicitud.

DELETE

Esto indica que el servidor debe destruir el documento en la ubicación indicada por el URI de la solicitud. Muy pocas implementaciones del servidor HTTP de Internet se realizarán cuando reciban una solicitud DELETE, por razones bastante obvias.

TRACE

Esto proporciona un mecanismo de nivel de capa de aplicación para permitir a los clientes inspeccionar la solicitud que ha enviado en el momento en que llega al servidor de destino. Esto es principalmente útil para determinar el efecto que puede tener cualquier servidor proxy entre el cliente y el servidor de destino en el mensaje de solicitud.

CONNECT

HTTP 1.1 se reserva el nombre para un método CONNECT, pero no define su uso, ni siquiera su propósito. Algunas implementaciones de servidores proxy han usado desde entonces el método CONNECT para facilitar el túnel HTTP.


Nunca he intentado usar PUT (GET POST y FILES fueron suficientes para mis necesidades), pero este ejemplo es de los documentos php, por lo que podría ayudarlo (http://php.net/manual/en/features.file-upload). put-method.php):

<?php /* PUT data comes in on the stdin stream */ $putdata = fopen("php://input", "r"); /* Open a file for writing */ $fp = fopen("myputfile.ext", "w"); /* Read the data 1 KB at a time and write to the file */ while ($data = fread($putdata, 1024)) fwrite($fp, $data); /* Close the streams */ fclose($fp); fclose($putdata); ?>


Solo sigue lo que dice el DOC :

<?php /* PUT data comes in on the stdin stream */ $putdata = fopen("php://input", "r"); /* Open a file for writing */ $fp = fopen("myputfile.ext", "w"); /* Read the data 1 KB at a time and write to the file */ while ($data = fread($putdata, 1024)) fwrite($fp, $data); /* Close the streams */ fclose($fp); fclose($putdata); ?>

Esto debería leer todo el archivo que está en la secuencia PUT y guardarlo localmente, luego podría hacer lo que quiera con él.


Use POST e incluya un encabezado X para indicar el método real (PUT en este caso). Por lo general, es así como se trabaja alrededor de un firewall que no permite métodos distintos de GET y POST. Simplemente declare el buggy de PHP (ya que se niega a manejar cargas útiles PUT de varias partes, ES buggy), y trátelo como lo haría con un firewall obsoleto / draconiano.

Las opiniones sobre lo que significa PUT en relación con GET son solo eso, opiniones. El HTTP no hace tal requisito. Simplemente establece ''equivalente'' ... depende del diseñador determinar qué significa ''equivalente''. Si su diseño puede aceptar un PUT de carga de múltiples archivos y producir una representación ''equivalente'' para un GET posterior para el mismo recurso, eso es correcto y técnico, tanto técnica como filosóficamente, con las especificaciones HTTP.