فهرست منبع

Fixing ZF-5744:
- Multiple file uploads with the same form element name are now possible.
- Adding documentation about minor BC breakage


git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@16882 44c647ce-9c0f-0410-b52a-842ac1e357ba

shahar 16 سال پیش
والد
کامیت
e40176bd1f

+ 1 - 0
documentation/manual/en/manual.xml.in

@@ -250,6 +250,7 @@
         <xi:include href="module_specs/Zend_Http_Client.xml" />
         <xi:include href="module_specs/Zend_Http_Client-Advanced.xml" />
         <xi:include href="module_specs/Zend_Http_Client-Adapters.xml" />
+        <xi:include href="module_specs/Zend_Http_Client-Migration.xml" />
         <xi:include href="module_specs/Zend_Http_Cookie-Handling.xml" />
         <xi:include href="module_specs/Zend_Http_Response.xml" />
     </chapter>

+ 78 - 0
documentation/manual/en/module_specs/Zend_Http_Client-Migration.xml

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.http.client.migration">
+
+    <title>Migrating from previous versions</title>
+
+    <para>
+        While the external API of <classname>Zend_Http_Client</classname> has remained 
+        consistent throughout the 1.x brach of Zend Framework, some changes were introduced
+        to the internal structure of <classname>Zend_Http_Client</classname> and its related
+        classes. 
+    </para>
+    
+    <para>
+        These changes should have no affect on code using <classname>Zend_Http_Client</classname>
+        - but may have an effect on PHP classes overloading or extending it. If your application
+        subclasses <classname>Zend_Http_Client</classname>, it is highly recommended to review
+        the following changes before upgrading Zend Framework.   
+    </para>
+
+    <sect2 id="zend.http.client.migration.tozf19">
+        <title>Migrating from 1.8 or older to 1.9 or newer</title>
+        <sect3 id="zend.http.client.migration.tozf19.fileuploadsarray">
+            <title>Changes to internal uploaded file information storage</title>
+
+            <para>
+                In version 1.9 of Zend Framework, there has been a change in the way
+                <classname>Zend_Http_Client</classname> internally stores information about
+                files to be uploaded, set using the <classname>Zend_Http_Client::setFileUpload()</classname> 
+                method.
+            </para>
+            
+            <para>
+                This change was introduced in order to allow multiple files to be uploaded
+                with the same form name, as an array of files. More information about this issue
+                can be found in <ulink url="http://framework.zend.com/issues/browse/ZF-5744">this bug report</ulink>.
+            </para>
+
+            <example id="zend.http.client.migration.tozf19.fileuploadsarray.example">
+                <title>Internal storage of uploaded file information</title>
+                
+                <programlisting language="php"><![CDATA[
+// Upload two files with the same form element name, as an array
+$client = new Zend_Http_Client();
+$client->setFileUpload('file1.txt', 'userfile[]', 'some raw data', 'text/plain');
+$client->setFileUpload('file2.txt', 'userfile[]', 'some other data', 'application/octet-stream');
+
+// In Zend Framework 1.8 or older, the value of the protected member $client->files is:
+// $client->files = array(
+//     'userfile[]' => array('file2.txt', 'application/octet-stream', 'some other data')
+// );
+
+// In Zend Framework 1.9 or newer, the value of $client->files is:
+// $client->files = array(
+//     array(
+//         'formname' => 'userfile[]',
+//         'filename' => 'file1.txt,
+//         'ctype'    => 'text/plain',
+//         'data'     => 'some raw data'
+//     ),
+//     array(
+//         'formname' => 'userfile[]',
+//         'filename' => 'file2.txt',
+//         'formname' => 'application/octet-stream',
+//         'formname' => 'some other data'
+//     )
+// );
+]]></programlisting>
+            </example>
+            
+            <para>
+                As you can see this change permits the usage of the same form element name with
+                more than one file - however, it introduces a subtle backwards-compatibility change
+                and as such should be noted. 
+            </para>
+        </sect3>
+    </sect2>
+</sect1>

+ 9 - 4
library/Zend/Http/Client.php

@@ -691,7 +691,12 @@ class Zend_Http_Client
         // Force enctype to multipart/form-data
         $this->setEncType(self::ENC_FORMDATA);
 
-        $this->files[$formname] = array(basename($filename), $ctype, $data);
+        $this->files[] = array(
+            'formname' => $formname, 
+            'filename' => basename($filename), 
+            'ctype'    => $ctype, 
+            'data'     => $data
+        );
 
         return $this;
     }
@@ -1058,9 +1063,9 @@ class Zend_Http_Client
                     }
 
                     // Encode files
-                    foreach ($this->files as $name => $file) {
-                        $fhead = array(self::CONTENT_TYPE => $file[1]);
-                        $body .= self::encodeFormData($boundary, $name, $file[2], $file[0], $fhead);
+                    foreach ($this->files as $file) {
+                        $fhead = array(self::CONTENT_TYPE => $file['ctype']);
+                        $body .= self::encodeFormData($boundary, $file['formname'], $file['data'], $file['filename'], $fhead);
                     }
 
                     $body .= "--{$boundary}--\r\n";

+ 25 - 1
tests/Zend/Http/Client/SocketTest.php

@@ -778,11 +778,35 @@ class Zend_Http_Client_SocketTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * Test that one can upload multiple files with the same form name, as an 
+     * array
+     *
+     * @link http://framework.zend.com/issues/browse/ZF-5744
+     */
+    public function testMutipleFilesWithSameFormNameZF5744()
+    {
+        $rawData = 'Some test raw data here...';
+        
+        $this->client->setUri($this->baseuri . 'testUploads.php');
+        
+        $files = array('file1.txt', 'file2.txt', 'someotherfile.foo');
+        
+        $expectedBody = '';
+        foreach($files as $filename) {
+            $this->client->setFileUpload($filename, 'uploadfile[]', $rawData, 'text/plain');
+            $expectedBody .= "uploadfile $filename text/plain " . strlen($rawData) . "\n";
+        }
+        
+        $res = $this->client->request('POST');
+
+        $this->assertEquals($expectedBody, $res->getBody(), 'Response body does not include expected upload parameters');
+    }
+    
+    /**
      * Test that lines that might be evaluated as boolean false do not break
      * the reading prematurely.
      *
      * @see http://framework.zend.com/issues/browse/ZF-4238
-     *
      */
     public function testZF4238FalseLinesInResponse()
     {

+ 7 - 1
tests/Zend/Http/Client/_files/testUploads.php

@@ -2,6 +2,12 @@
 
 if (! empty($_FILES)) {
 	foreach ($_FILES as $name => $file) {
-		echo $name . " " . $file['name'] . " " . $file['type'] . " " . $file['size'] . "\n";
+	    if (is_array($file['name'])) {
+	        foreach($file['name'] as $k => $v) {
+                echo "$name $v {$file['type'][$k]} {$file['size'][$k]}\n";
+            }
+	    } else {
+	        echo "$name {$file['name']} {$file['type']} {$file['size']}\n";
+	    }
 	}
 }