Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour à tous,
J'utilise la classe "Zend_File_Transfer_Adapter_Http" pour transférer des fichiers du client vers le serveur, via HTTP.
Voici un petit scripte de test qui fonctionne comme je le souhaite.
<html> <?php $adapter = null; $files = null; $txt = null; error_reporting(E_ALL|E_STRICT); ini_set("display_errors", "on"); require_once 'Zend' . DIRECTORY_SEPARATOR . 'Loader' . DIRECTORY_SEPARATOR . 'Autoloader.php'; Zend_Loader_Autoloader::getInstance(); try { // Création de l'adaptateur pour la réception du fichier. $adapter = new Zend_File_Transfer_Adapter_Http(); // -------------------------------------------------------------------------------- // Définition des filtres. // -------------------------------------------------------------------------------- // Tous les fichiers chargés seront déposés dans le répertoire "/tmp/upload/". // Les fichiers se voient attribués des noms uniques. $adapter->addFilter('Rename', '/tmp/upload/'); // -------------------------------------------------------------------------------- // Définition des validateurs. // http://framework.zend.com/manual/fr/zend.file.transfer.validators.html // -------------------------------------------------------------------------------- // Limitation de la taille maximum du fichier chargé. // La valeur du deuxième argument signifie que le chargement s'interrompt si la taille du fichier de respecte pas les limites imposées. $adapter->addValidator('Size', true, array('min' => 20, 'max' => 2000000)); // Si le fichier téléchargé existe déjà, alors on annule le chargement. // La valeur du deuxième argument signifie que le chargement s'interrompt si la taille du fichier de respecte pas les limites imposées. // L'activation du filtre "Rename" rend cette validation inutile. $adapter->addValidator('NotExists', true, '/tmp'); // Chargement des fichiers. if (FALSE === $adapter->receive()) { echo 'ERROR:'; echo '<ul>'; foreach ($adapter->getMessages() as $message) { echo '<li>' . $message . "</li>\n"; } echo '</ul>'; echo '<br />'; exit; } // Extraction des informations relatives au(x) fichier(s) reçu(s). $files = $adapter->getFileInfo(); echo '<pre>' . var_dump_html($files) . "</pre>\n"; // Nombre de fichiers téléchargés. echo "Number of uploaded files: " . count($files) . "<br /><br />"; // Le fichier désigné par le "nom de transfert" "uploadedfile1" a-t-il été reçu? if ($adapter->isUploaded('uploadedfile1')) { echo '<b>uploadedfile1</b> is uploaded.<br /><br />'; } else { echo '<b>uploadedfile1</b> is not uploaded.<br /><br />'; } // Affichage des informations relatives au fichier téléchargé. echo '<ul>'; if ($adapter->isUploaded('uploadedfile1')) { echo '<li>Path to the temporary directory on the server used to store the received file: ' . $adapter->getDestination('uploadedfile1') . '</li>'; echo '<li>Name of the file: ' . $adapter->getFileName('uploadedfile1', false) . '</li>'; echo '<li>Full path to the file, on the server: ' . $adapter->getFileName('uploadedfile1', true) . '</li>'; echo '<li>Type: ' . $adapter->getMimeType('uploadedfile1') . '</li>'; $adapter->setOptions(array('useByteString' => false)); echo '<li>Size of the file, in bytes: ' . $adapter->getFileSize('uploadedfile1') . '</li>'; $adapter->setOptions(array('useByteString' => true)); echo '<li>Size of the file, human readable: ' . $adapter->getFileSize('uploadedfile1') . '</li>'; } echo '</ul>'; } catch (Exception $e) { echo "ERROR: " . "Fichier: " . $e->getFile() . " ligne: " . $e->getLine() . ' : ' . $e->getMessage() . "\n"; } // Validation. function var_dump_html ($inVar) { $txt = null; ob_start(); var_dump($inVar); $txt = ob_get_contents(); ob_end_clean(); return $txt; } echo 'OK'; ?>
Pour information, voici le formulaire HTML associé :
<html> <body> <form enctype="multipart/form-data" action="http://toto.com/tools/upload.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="uploadedfile1" type="file" /> <br /> Choose a file to upload: <input name="uploadedfile2" type="file" /> <br /> <input type="submit" value="Upload File" /> </form> </body> </html>
La description du filtre "Rename" n'est pas très claire .
source : le nom et le dossier de l'ancien fichier qui doit être renommé.
target : le nouveau dossier ou nom du fichier.
overwrite : paramètre si l'ancien fichier écrase le nouveau fichier s'il existe déjà. La valeur par défaut est FALSE.
// Tous les fichiers chargés seront déposés dans le répertoire "/tmp/upload/". // Les fichiers se voient attribués des noms uniques. $adapter->addFilter('Rename', '/tmp/upload/');
On constate, à l'exécution, que tous les fichiers sont stockés dans le répertoire '/tmp/upload/'. Et ils portent tous les noms distincts.
ls -l /tmp/upload/ total 928 -rw-r--r-- 1 www-data root 20992 2010-01-25 12:23 php0zhztX -rw-r--r-- 1 www-data root 75264 2010-01-25 12:23 php6Wm4WH -rw-r--r-- 1 www-data root 10702 2010-01-25 13:39 phpaEHvOv -rw-r--r-- 1 www-data root 10702 2010-01-25 14:41 phpBEkRQV -rw-r--r-- 1 www-data root 20992 2010-01-25 12:24 phpfGPUzI -rw-r--r-- 1 www-data root 20992 2010-01-25 12:23 phpfKCnqy -rw-r--r-- 1 www-data root 10702 2010-01-25 13:39 phpiMidpR
C'est justement le comportement que je désire obtenir... Mais cela ne "colle" pas avec ce qui est écrit dans la documentation
// Tous les fichiers chargés seront déposés dans le répertoire "/tmp/upload/". // Les fichiers se voient attribués des noms uniques. $adapter->addFilter('Rename', '/tmp/upload/', 'uploadedfile1');
Produit :
Notice: Undefined index: filters in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175 Warning: array_search() [function.array-search]: Wrong datatype for second argument in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175
Et
// Tous les fichiers chargés seront déposés dans le répertoire "/tmp/upload/". // Les fichiers se voient attribués des noms uniques. $adapter->addFilter('Rename', '/tmp/upload/', '/tmp/newupload');
ls -l total 148 drwxr-sr-x 2 tornado root 4096 2010-01-25 14:41 newupload drwxrwxrwx 2 tornado root 4096 2010-01-25 14:46 upload
Produit :
Notice: Undefined index: filters in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175 Warning: array_search() [function.array-search]: Wrong datatype for second argument in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175 Notice: Undefined index: filters in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175 Warning: array_search() [function.array-search]: Wrong datatype for second argument in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175
Quelqu'un peut-il m'expliquer à quoi correspond le deuxième argument du filtre?
Merci,
A+
Dernière modification par Denis. Beurive (26-01-2010 19:05:46)
Hors ligne
Attention, tu fais une erreur sur la syntaxe :
/** * Adds a new filter for this class * * @param string|array $filter Type of filter to add * @param string|array $options Options to set for the filter * @param string|array $files Files to limit this filter to * @return Zend_File_Transfer_Adapter */ public function addFilter($filter, $options = null, $files = null)
Hors ligne
nORKy a écrit:
Attention, tu fais une erreur sur la syntaxe :
Code:
/** * Adds a new filter for this class * * @param string|array $filter Type of filter to add * @param string|array $options Options to set for the filter * @param string|array $files Files to limit this filter to * @return Zend_File_Transfer_Adapter */ public function addFilter($filter, $options = null, $files = null)
Hello,
Je cite la documentation :
$upload = new Zend_File_Transfer_Adapter_Http();
// Paramètre un nouveau dossier pour tous les fichiers
$upload->addFilter('Rename', 'C:\mypics\new');
Cela fonctionne.
$upload = new Zend_File_Transfer_Adapter_Http();
// Paramètre un nouveau dossier seulement pour uploadfile1
$upload->addFilter('Rename', 'C:\mypics\newgifs', 'uploadfile1');
Cela ne fonctionne pas.
Et lorsque que je tente d'utiliser un tableau associatif pour les options... j'ai l'impression que rien ne fonctionne.
Peux-tu me donner la ligne de code correcte qui correspond à l'utilisation d'un tableau associatif pour spécifier des options?
Merci,
Denis
Hors ligne
Hello,
Quelle version de ZF ?
Il semblerait qu'il y ait une notation alternative : http://framework.zend.com/manual/1.10/e … ters.usage :
$upload = new Zend_File_Transfer(); // Set a new destination path $upload->addFilter('Rename', 'C:\picture\uploads'); // Set a new destination path and overwrites existing files $upload->addFilter('Rename', array('target' => 'C:\picture\uploads', 'overwrite' => true));
@+
Hors ligne
mikaelkael a écrit:
Hello,
Je te remercie pour ta réponse.
Quelle version de ZF ?
Il semblerait qu'il y ait une notation alternative : http://framework.zend.com/manual/1.10/e … ters.usage :Code:
$upload = new Zend_File_Transfer(); // Set a new destination path $upload->addFilter('Rename', 'C:\picture\uploads'); // Set a new destination path and overwrites existing files $upload->addFilter('Rename', array('target' => 'C:\picture\uploads', 'overwrite' => true));@+
Hello!
Quelle version de ZF ?
RELEASE INFORMATION
-------------------
Zend Framework 1.9.4 (r18529).
Released on October 12, 2009.
J'ai essayé plusieurs choses :
Test 1
Si je n'applique pas de filtre, les fichiers sont déposés dans le répertoire, avec leurs noms d'origine.
ls -l /tmp
total 200
-rw-r--r-- 1 www-data root 14126 2010-01-25 18:56 Capture1.PNG
-rw-r--r-- 1 www-data root 47913 2010-01-25 18:56 Capture.PNG
Test 2
$adapter->addFilter('Rename', '/tmp/upload');
Les fichiers chargés sont stockés dans le répertoire '/tmp/upload'. sous des noms visiblement choisis de telle façon qu'ils sont uniques.
ls -l /tmp/upload/
total 560
-rw-r--r-- 1 www-data root 50637 2010-01-25 16:58 php2gs2Q4
-rw-r--r-- 1 www-data root 50637 2010-01-25 17:50 phpBQXz8p
-rw-r--r-- 1 www-data root 50637 2010-01-25 17:49 phpDO4N4j
-rw-r--r-- 1 www-data root 50637 2010-01-25 17:49 phpLe0mIi
NOTE : D'après la documentation, ce code est censé changer le répertoire de stockage, mais pas le nom du fichier.
Pour information, le même comportement est obtenu avec le code suivant :
// Set a new destination path
$upload->addFilter('Rename', 'C:\picture\uploads');
Donc, de deux choses l'une :
La documentation n'est pas en phase avec le code.
Le code est buggé.
Test 3
$adapter->addFilter('Rename', array('target' => '/tmp/upload', 'overwrite' => true));
Le résultat est en tous points identique à celui du test 2.
QUESTION : À quoi sert l'option 'overwrite' dans ce cas? (puisque, de toutes les façons, les fichiers portent des noms distincts).
Il semble que le changement du répertoire de stockage entraîne automatquement un renommage des fichiers. Peut-être que c'est cela la raison d'être de ce filtre. Or, à lire la documentation, on a l'impression que ce filtre permet de faire plus de choses...
A+, Denis
Dernière modification par Denis. Beurive (25-01-2010 19:18:32)
Hors ligne
Et est-ce que le résultat ne serait pas logique ??
Le filtre Rename fonctionne sur des réperoires OU des fichiers
/tmp/upload est un répertoire ? on est d'accord ?
Donc, qu'est ce qui se passe quand tu copies ton fichier ?
Quand tu envois un fichier, PHP (et ca, c'est pour tout le monde), donc un nom unique et le place dans un répertoire temporaire.
Toi, tu appliques le filtre 'Rename' en donnant un répertoire.
Ainsi, quand tu appelles receive(), c'est comme si tu copiais /tmp/phpXXX => /tmp/upload
Le comportement du système est simple logique : déplacement d'un fichier dans un répertoire
EDIT :
la fonction overwrite est dans le cas d'un fichier, si tu fais /tmp/phpXXX => /tmp/upload/nomdefichier, alors, si il existe déjà le fichier, avec overwrite, il l'écrase, sinon (leve une exception ?)
Dernière modification par nORKy (26-01-2010 10:16:41)
Hors ligne
nORKy a écrit:
Et est-ce que le résultat ne serait pas logique ??
Le filtre Rename fonctionne sur des réperoires OU des fichiers
/tmp/upload est un répertoire ? on est d'accord ?
Donc, qu'est ce qui se passe quand tu copies ton fichier ?
Quand tu envois un fichier, PHP (et ca, c'est pour tout le monde), donc un nom unique et le place dans un répertoire temporaire.
Toi, tu appliques le filtre 'Rename' en donnant un répertoire.
Ainsi, quand tu appelles receive(), c'est comme si tu copiais /tmp/phpXXX => /tmp/upload
Le comportement du système est simple logique : déplacement d'un fichier dans un répertoire
EDIT :
la fonction overwrite est dans le cas d'un fichier, si tu fais /tmp/phpXXX => /tmp/upload/nomdefichier, alors, si il existe déjà le fichier, avec overwrite, il l'écrase, sinon (leve une exception ?)
Salut,
Effectivement, je pense que l'explication que tu donnes est la bonne.
Lors de la réception d'un fichier en provenance d'un client, le comportement de PHP est effectivement de stocker le contenu du fichier téléchargé dans un fichier dont le nom est choisi de telle façon que tous les noms des "fichiers de stockage" sont distincts.
La raison d'être du filtre est de modifier ce comportement par défaut.
Cas d'utilisation 1
$adapter = new Zend_File_Transfer_Adapter_Http(); $adapter->addFilter('Rename', array( 'target' =>'/tmp/upload/toto', 'overwrite' => true) );
ls -l /tmp/upload/
total 0
Tous les fichiers chargés sont stockés sous le fichier "/tmp/upload/toto". Et, si un fichier a déjà été chargé, une erreur est remontée (car le fichier "/tmp/upload/toto" existe déjà).
Cas d'utilisation 2
$adapter = new Zend_File_Transfer_Adapter_Http(); $adapter->addFilter('Rename', array( 'target' =>'/tmp/upload' ) );
Tous les fichiers chargés sont stockés sous le répertoire. Les fichiers ne sont pas renommés : Les noms de fichiers de stockages sont donc choisis arbitrairement par PHP de telle façon que tous les fichiers de stockage ont des noms distincts.
Note 1: Le code suivant n'a pas de sens. Le code suivant n'a pas de sens, dans la mesure où l'option qui autorise l'écrasement des fichiers existants est inutile.
$adapter = new Zend_File_Transfer_Adapter_Http(); $adapter->addFilter('Rename', array( 'target' =>'/tmp/upload', 'overwrite' => true ) );
Note 2: Le code suivant est équivalent.
$adapter = new Zend_File_Transfer_Adapter_Http(); $adapter->addFilter('Rename', '/tmp/upload');
Cas d'utilisation 3 (je ne comprends pas vraiment)
Je cite la documentation.
1. $upload = new Zend_File_Transfer_Adapter_Http();
2.
3. // Paramètre un nouveau dossier pour tous les fichiers
4. $upload->addFilter('Rename', 'C:\mypics\new');
5.
6. // Paramètre un nouveau dossier seulement pour uploadfile1
7. $upload->addFilter('Rename', 'C:\mypics\newgifs', 'uploadfile1');
Je teste la ligne 7 de l'exemple.
<html>
<body>
<form enctype="multipart/form-data" action="http://toto.com/tools/upload.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="MonImage" type="file" /> <br /> <input type="submit" value="Upload File" /> </form> </body> </html>
// Notez bien: "photo" et non "MonImage". $adapter->addFilter('Rename', '/tmp/upload', 'photo');
Si je comprends la philosophie de la classe :
1. Le contenu du fichier désigné par le "nom de formulaire" "photo" sera déposé dans le répertoire "/tmp/upload'".
2. Les contenus des fichiers désignés par des "noms de formulaire" différents (autre que "photo") feront l'objet du traitement par défaut de la classe : Dépôt du contenu du fichier chargé dans le répertoire "/tmp" (pas "/tmp/upload"), dans un fichier qui porte le nom du fichier d'origine.
Résultat :
Notice: Undefined index: filters in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175
Warning: array_search() [function.array-search]: Wrong datatype for second argument in /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php on line 175
Warning: Cannot modify header information - headers already sent by (output started at /home/toto.com/www/libs/Zend/library/Zend/File/Transfer/Adapter/Http.php:175) in /home/toto.com/www/elgg1.6.1/tools/upload.php on line 62
QUESTION : Comment expliques-tu cela? J'admets que mon interprétation de la documention est peut-être fausse. Cela dit, la documentation devrait être précisée.
Et, autre test, avec cette fois :
<form enctype="multipart/form-data" action="http://toto.com/tools/upload.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="photo" type="file" /> <br /> <input type="submit" value="Upload File" /> </form> </body> </html>
// Notez bien: "photo". $adapter->addFilter('Rename', '/tmp/upload', 'photo');
Là, ça fonctionne.
Conclusion : Si des modalités de filtration sont définies pour un "nom de formulaire", alors l'utilisation de "noms de formulaires" différents génère des erreurs PHP. Or, de mon point de vue, le comportement qui devrait s'appliquer lors des cas non prévus est le comportement par défaut. Cela me fait dire qu'il y a un problème dans le code de cette classe. Qu'en penses-tu?
A+
Dernière modification par Denis. Beurive (26-01-2010 19:10:45)
Hors ligne
Pages: 1