|
PUT method supportPHP provides support for the HTTP PUT method used by some clients to store files on a server. PUT requests are much simpler than a file upload using POST requests and they look something like this: put /path/filename.php http/1.1
this would normally mean that the remote client would like to save
the content that follows as: Script PUT /put.php This tells Apache to send all PUT requests for URIs that match the context in which you put this line to the put.php script. This assumes, of course, that you have PHP enabled for the .php extension and PHP is active. The destination resource for all PUT requests to this script has to be the script itself, not a filename the uploaded file should have.
With PHP 4 and following you would then do something like the following in
your put.php. This would copy the contents of the uploaded file to the
file Example 5.5. Saving HTTP PUT files with PHP 4<?php
Note:
All documentation below applies to PHP 3 only. Example 5.6. Saving HTTP PUT files with PHP 3<?php copy($PHP_UPLOADED_FILE_NAME, $DOCUMENT_ROOT . $REQUEST_URI); ?>
The only
trick here is that when PHP sees a PUT-method request it stores
the uploaded file in a temporary file just like those handled by
the POST-method.
When the request ends, this temporary file is deleted. So, your
PUT handling PHP script has to copy that file somewhere. The
filename of this temporary file is in the Code Examples / Notes » features.file_upload.put_methodgomez_nospam_pixline_dot_net
Trying to capture a PUT stream into a single variable seems not to be allowed, probably because of the non presence of some kind of EOF. In this way save a PUT request into a database isn't easy. The only way I find would be output to a cache file, then either insert filename into db or read again its content and place it in some kind of query. yaogzhan
PUT raw data comes in php://input, and you have to use fopen() and fread() to get the content. file_get_contents() is useless. The HTTP PUT request MUST contain a Content-Length header to specify the length (in bytes) of the body, or the server will not be able to know when the input stream is over. This is the common problem for many to find the php://input empty if no such header available. This should make PUT work properly on win32 using PHP5.1.1 and apache2. warhog
NOTE: The <Script>-Directive can not be placed in .htaccess files. So if you're having shared webspace and no access to the apache-configuration file you will have little chance to make something like this work. But you can solve the problem, using mod_rewrite (for Apache) - for further information see the documentation at http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html mikeb
I have spent a lot of time trying to make PUT work with Apache 2.0.40. I have not yet been able to find any way of making the Script directive invoke php via mod_php, the only way has been to have a file called example.cgi and invoke it via CGI, with the file starting #!/usr/bin/php so the PHP interpreter is invoked through the CGI mechanism and not as a module. If there IS a way of making it work 'right' I'd love to know! After six hours of messing around, I've settled for CGI. The error messages in the apache error log are significantly misleading and the whole thing has been an exercise in frustration. Attempts to use AddHandler and all 'normal' ways of trying to persuade Apache to do this have been fruitless. It does seem as if PUT can only be handled by CGI invocation. php
I can only make it work when I am using PHP as CGI, not as an Apache module. I am using the version of PHP/Apahce that is shipped with Debian/testing. You have to load the action_module, but not the put_module in Apache config. warhog
Here's my solution on my Note below The .htacces-File Options FollowSymLinks RewriteEngine on RewriteBase !!!The Path of your PUT-Upload-Folder, relative to the DocumentRoot!!! RewriteRule ^index\.php$ - [L] RewriteRule ^(.*)$ index.php?url=$1 [L] index.php: <?php if ($_SERVER['REQUEST_METHOD'] == "PUT") { $f = fopen(basename($_SERVER['REQUEST_URI']), "w"); $s = fopen("php://input", "r"); while($kb = fread($s, 1024)) { fwrite($f, $kb, 1024); } fclose($f); fclose($s); Header("HTTP/1.1 201 Created"); } elseif ($_SERVER['REQUEST_METHOD'] == "GET") { readfile(basename($_SERVER['REQUEST_URI'])); } ?> Testes with Apache 2 and PHP 5, php as a module (win32) gherson
A Case Study: To set up publishing with Netscape 7.2 Composer to Apache/PHP, no need to use CGI (which I tried unsuccessfully for too long) or to alter Apache's httpd.conf. I needed only to click Publish As, fill in put2disk.php as the filename (where its contents are the below), and fill in that file's dir as the "Publishing address". XAMPP 1.4.14: Apache/2.0.54 (Win32) mod_ssl/2.0.54 OpenSSL/0.9.7g PHP/5.0.4. <? // filename: put2disk.php. //file_put_contents ("get_def.out", print_r (get_defined_vars(), TRUE)); // debugging // Two slurp methods: (a) didn't work, (b) did. //$stdin_rsc = fopen("php://input", "r"); //$putdata=''; //while ($putdata .= fread($stdin_rsc, 1024)); // a. Hangs the "Publishing..." dialog. //while (!feof($stdin_rsc)) $putdata.=fread($stdin_rsc, 8192); // b. Worked, but file_get_contents is faster. //fclose($stdin_rsc); // All that's nec: $putdata=file_get_contents('php://input'); // Not php://stdin! (When the ability to see error messages isn't available, the doc (this manual page) needs to be more accurate.) file_put_contents("stdin.out",$putdata); ?> |