PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Aπομακρυσμένα αρχεία> <Χειρίζοντας upload αρχείων
Last updated: Sun, 25 Nov 2007

view this page in

Υποστήριξη της PUT μεθόδου

Η υποστήριξη για την PUT μέθοδο έχει αλλάξει μεταξύ της PHP 3 και της PHP 4. Στην PHP 4, πρέπει να χρησιμοποιείτε το standard input stream για να διαβάσετε τα περιεχόμενα ενός HTTP PUT.

Example#1 Αποθηκεύοντας HTTP PUT αρχεία με την PHP 4

<?php
/* PUT data comes in on the stdin stream */
$putdata fopen("php://stdin","r");

/* Open a file for writting */
$fp fopen("myputfile.ext","w");

/* Read the data 1kb at a time
   and write to the file */
while ($data fread($putdata,1024))
  
fwrite($fp,$data);

/* Close the streams */
fclose($fp);
fclose($putdata);
?>

Note: Όλη η τεκμηρίωση που ακολουθεί ισχύει για την PHP 3 μόνο.

Η PHP προσφέρει υποστήριξη για την HTTP PUT μέθοδο που χρησιμοποιείται από client σαν τους Netscape Composer και W3C Amaya. Οι PUT request είναι αρκετά απλούστερες από ένα upload αρχείου και μοιάζουν κάπως έτσι:

PUT /path/filename.html HTTP/1.1
     

Αυτό κανονικά σημαίνει πως ο remote client θα ήθελε να αποθηκεύσει τα περιεχόμενα που ακολουθούν: /path/filename.html στο web tree σας. Προφανώς δεν είναι και τόσο καλή ιδέα ο Apache ή η PHP να αφήνουν αυτόματα οποιονδήποτε να κάνει overwrite αρχεία στο web tree σας. Έτσι, για να χειριστείτε ένα τέτοιο request πρέπει πρώτα να πείτε στον web server σας πως θέλετε ένα συγκεκριμένο PHP script να χειριστεί το request. Στον Apache το κάνετε αυτό με το Script directive. Μπορεί να τοποθετηθεί σχεδόν οπουδήποτε μέσα στο αρχείο ρυθμίσεων του Apache. Ένα συνηθισμένο μέρος είναι μέσα σε ένα <Directory> μπλοκ ή πιθανώς μέσα σε ένα <Virtualhost> μπλοκ. Μια γραμμή σαν και αυτή θα κάνει το κόλπο:

Script PUT /put.php
     

Αυτό λέει στον Apache να στέλνει όλα τα PUT request για URI που ταιριάζουν στο περιεχόμενο στο οποίο τοποθετήσατε αυτή τη γραμμή στο put.php script σας. Αυτό υποθέτει, φυσικά, πως έχετε την PHP συνδεδεμένη για την .php επέκταση και πως η PHP είναι ενεργοποιημένη.

Μέσα στο put.php αρχείο σας θα θέλετε να κάνετε κάτι τέτοιο:

<?php copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI); ?>

Αυτό θα αντιγράψει το αρχείο στην τοποθεσία που ζητήθηκε από τον remote client. Θα θέλετε πιθανώς να κάνετε κάποιους έλεγχους ή/και να αναγνωρίσετε των χρήστη πριν να εκτελέσει αυτή την αντιγραφή του αρχείου. Το μόνο κόλπο εδώ είναι πως όταν η PHP δει ένα request μέσω PUT μεθόδου αποθηκεύει το αρχείο που έχει γίνει upload σε ένα προσωρινό αρχείο όπως εκίνα που χειρίζεται η POST-μέθοδος. Όταν το request τελειώσει, αυτό το προσωρινό αρχείο διαγράφεται. Έτσι, το PHP script σας που χειρίζεται το PUT πρέπει να αντιγάψει το αρχείο αυτό κάπου αλλού. Το όνομα του προσωρινού αυτού αρχείου είναι μέσα στην $PHP_PUT_FILENAME μεταβλητή, και μπορείτε να δείτε το προτεινόμενο όνομα προορισμού στο $REQUEST_URI (μπορεί να διαφέρει σε web server εκτός του Apache). Αυτό το όνομα αρχείου προορισμού είναι αυτό που ο remote client ορίζει. Δεν χρειάζεται να ακούσετε τον client. Θα μπορούσατε, για παράδειγμα, να αντιγράφετε όλα τα αρχεία που γίνονται upload σε ένα ειδικό κατάλογο για τα upload.



add a note add a note User Contributed Notes
Υποστήριξη της PUT μεθόδου
yaogzhan at gmail dot com
14-Dec-2005 04:01
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 at warhog dot net
20-Sep-2005 02:11
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)
warhog at warhog dot net
20-Sep-2005 01:22
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
gherson
15-Aug-2005 02:16
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);
?>
gomez_NOSPAM_pixline_dot_net
18-Apr-2004 12:59
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.
mikeb at mikebanahan dot com
03-Nov-2003 02:41
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 at dreier dot nu
13-Feb-2003 10:21
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.

 
show source | credits | stats | sitemap | contact | advertising | mirror sites