| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.file.transfer.introduction">
- <title>Zend_File_Transfer</title>
- <para>
- <classname>Zend_File_Transfer</classname> provides extensive support for file uploads and
- downloads. It comes with built-in validators for files plus functionality to change files
- with filters. Protocol adapters allow <classname>Zend_File_Transfer</classname> to expose
- the same <acronym>API</acronym> for transport protocols like <acronym>HTTP</acronym>, FTP,
- WEBDAV and more.
- </para>
- <note>
- <title>Limitation</title>
- <para>
- The current implementation of <classname>Zend_File_Transfer</classname> is limited to
- <acronym>HTTP</acronym> Post Uploads. Other adapters supporting downloads and other
- protocols will be added in future releases. Unimplemented methods will throw an
- exception. For now, you should use
- <classname>Zend_File_Transfer_Adapter_Http</classname> directly. As soon as
- there are multiple adapters available you can use a common interface.
- </para>
- </note>
- <note>
- <title>Forms</title>
- <para>
- When you are using <classname>Zend_Form</classname> you should use the
- <acronym>API</acronym>s provided by <classname>Zend_Form</classname> and not
- <classname>Zend_File_Transfer</classname> directly. The file transfer support in
- <classname>Zend_Form</classname> is implemented with
- <classname>Zend_File_Transfer</classname>, so the information in this chapter may
- be useful for advanced users of <classname>Zend_Form</classname>.
- </para>
- </note>
- <para>
- The usage of <classname>Zend_File_Transfer</classname> is relatively simple. It consists of
- two parts. The <acronym>HTTP</acronym> form does the upload, while the
- <classname>Zend_File_Transfer</classname> handles the uploaded files. See the following
- example:
- </para>
- <example id="zend.file.transfer.introduction.example">
- <title>Simple Form for Uploading Files</title>
- <para>
- This example illustrates basic file uploading.
- The first part is the file form. In our example there is one file to upload.
- </para>
- <programlisting language="xml"><![CDATA[
- <form enctype="multipart/form-data" action="/file/upload" method="POST">
- <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
- Choose a file to upload: <input name="uploadedfile" type="file" />
- <br />
- <input type="submit" value="Upload File" />
- </form>
- ]]></programlisting>
- <para>
- For convenience, you can use <link
- linkend="zend.form.standardElements.file">Zend_Form_Element_File</link> instead of
- building the <acronym>HTML</acronym> manually.
- </para>
- <para>
- The next step is to create the receiver of the upload. In our example the receiver is
- located at <filename>/file/upload</filename>. So next we will create the 'file'
- controller and the <methodname>upload()</methodname> action.
- </para>
- <programlisting language="php"><![CDATA[
- $adapter = new Zend_File_Transfer_Adapter_Http();
- $adapter->setDestination('C:\temp');
- if (!$adapter->receive()) {
- $messages = $adapter->getMessages();
- echo implode("\n", $messages);
- }
- ]]></programlisting>
- <para>
- This code listing demonstrates the simplest usage of
- <classname>Zend_File_Transfer</classname>. A local destination is set with the
- <methodname>setDestination()</methodname> method, then the
- <methodname>receive()</methodname> method is called. if there are any upload errors, an
- error will be returned.
- </para>
- </example>
- <note>
- <title>Attention</title>
- <para>
- This example is suitable only for demonstrating the basic <acronym>API</acronym> of
- <classname>Zend_File_Transfer</classname>. You should <emphasis>never</emphasis> use
- this code listing in a production environment, because severe security issues may be
- introduced. You should always use validators to increase security.
- </para>
- </note>
- <sect2 id="zend.file.transfer.introduction.adapters">
- <title>Supported Adapters for Zend_File_Transfer</title>
- <para>
- <classname>Zend_File_Transfer</classname> is designed to support a variety of adapters
- and transfer directions. With <classname>Zend_File_Transfer</classname> you can upload,
- download and even forward (upload one adapter and download with another adapter at the
- same time) files.
- </para>
- </sect2>
- <sect2 id="zend.file.transfer.introduction.options">
- <title>Options for Zend_File_Transfer</title>
- <para>
- <classname>Zend_File_Transfer</classname> and its adapters support different options.
- You can set all options either by passing them to the constructor or by calling
- <methodname>setOptions($options)</methodname>. <methodname>getOptions()</methodname>
- will return the options that are currently set. The following is a list of all supported
- options.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>ignoreNoFile</emphasis>: If this option is set to
- <constant>TRUE</constant>, all validators will ignore files that have not been
- uploaded by the form. The default value is <constant>FALSE</constant> which
- results in an error if no files were specified.
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.file.transfer.introduction.checking">
- <title>Checking Files</title>
- <para>
- <classname>Zend_File_Transfer</classname> has several methods that check for various
- states of the specified file. These are useful if you must process files after they have
- been uploaded. These methods include:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>isValid($files = null)</emphasis>: This method will check if the
- given files are valid, based on the validators that are attached to the files.
- If no files are specified, all files will be checked. You can call
- <methodname>isValid()</methodname> before calling
- <methodname>receive()</methodname>; in this case,
- <methodname>receive()</methodname> will not call
- <methodname>isValid()</methodname> internally again when receiving the file.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>isUploaded($files = null)</emphasis>: This method will check if the
- specified files have been uploaded by the user. This is useful when you have
- defined one or more optional files. When no files are specified, all files will
- be checked.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>isReceived($files = null)</emphasis>: This method will check if the
- given files have already been received. When no files are specified, all files
- will be checked.
- </para>
- </listitem>
- </itemizedlist>
- <example id="zend.file.transfer.introduction.checking.example">
- <title>Checking Files</title>
- <programlisting language="php"><![CDATA[
- $upload = new Zend_File_Transfer();
- // Returns all known internal file information
- $files = $upload->getFileInfo();
- foreach ($files as $file => $info) {
- // file uploaded ?
- if (!$upload->isUploaded($file)) {
- print "Why havn't you uploaded the file ?";
- continue;
- }
- // validators are ok ?
- if (!$upload->isValid($file)) {
- print "Sorry but $file is not what we wanted";
- continue;
- }
- }
- $upload->receive();
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.file.transfer.introduction.informations">
- <title>Additional File Informations</title>
- <para>
- <classname>Zend_File_Transfer</classname> can return additional information on files.
- The following methods are available:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>getFileName($file = null, $path = true)</emphasis>: This method
- will return the real file name of a transferred file.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getFileInfo($file = null)</emphasis>: This method will return all
- internal information for the given file.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getFileSize($file = null)</emphasis>: This method will return the
- real filesize for the given file.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getHash($hash = 'crc32', $files = null)</emphasis>: This method
- returns a hash of the content of a given transferred file.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>getMimeType($files = null)</emphasis>: This method returns the
- mimetype of a given transferred file.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- <methodname>getFileName()</methodname> accepts the name of the element as first
- parameter. If no name is given, all known filenames will be returned in an array. If the
- file is a multifile, you will also get an array. If there is only a single file a string
- will be returned.
- </para>
- <para>
- By default file names will be returned with the complete path. If you only need the file
- name without path, you can set the second parameter, <varname>$path</varname>, which
- will truncate the file path when set to <constant>FALSE</constant>.
- </para>
- <example id="zend.file.transfer.introduction.informations.example1">
- <title>Getting the Filename</title>
- <programlisting language="php"><![CDATA[
- $upload = new Zend_File_Transfer();
- $upload->receive();
- // Returns the file names from all files
- $names = $upload->getFileName();
- // Returns the file names from the 'foo' form element
- $names = $upload->getFileName('foo');
- ]]></programlisting>
- </example>
- <note>
- <para>
- Note that the file name can change after you receive the file, because all filters
- will be applied once the file is received. So you should always call
- <methodname>getFileName()</methodname> after the files have been received.
- </para>
- </note>
- <para>
- <methodname>getFileSize()</methodname> returns per default the real filesize in SI
- notation which means you will get <emphasis>2kB</emphasis> instead of
- <emphasis>2048</emphasis>. If you need only the plain size set the
- <property>useByteString</property> option to <constant>FALSE</constant>.
- </para>
- <example id="zend.file.transfer.introduction.informations.example.getfilesize">
- <title>Getting the size of a file</title>
- <programlisting language="php"><![CDATA[
- $upload = new Zend_File_Transfer();
- $upload->receive();
- // Returns the sizes from all files as array if more than one file was uploaded
- $size = $upload->getFileSize();
- // Switches of the SI notation to return plain numbers
- $upload->setOptions(array('useByteString' => false));
- $size = $upload->getFileSize();
- ]]></programlisting>
- </example>
- <note>
- <title>Client given filesize</title>
- <para>
- Note that the filesize which is given by the client is not seen as save input.
- Therefor the real size of the file will be detected and returned instead of the
- filesize sent by the client.
- </para>
- </note>
- <para>
- <methodname>getHash()</methodname> accepts the name of a hash algorithm as first
- parameter. For a list of known algorithms refer to
- <ulink url="http://php.net/hash_algos">PHP's hash_algos method</ulink>. If you don't
- specify an algorithm, the <emphasis>crc32</emphasis> algorithm will be used by default.
- </para>
- <example id="zend.file.transfer.introduction.informations.example2">
- <title>Getting the hash of a file</title>
- <programlisting language="php"><![CDATA[
- $upload = new Zend_File_Transfer();
- $upload->receive();
- // Returns the hashes from all files as array if more than one file was uploaded
- $hash = $upload->getHash('md5');
- // Returns the hash for the 'foo' form element
- $names = $upload->getHash('crc32', 'foo');
- ]]></programlisting>
- </example>
- <note>
- <title>Return value</title>
- <para>
- Note that if the given file or form name contains more than one file, the returned
- value will be an array.
- </para>
- </note>
- <para>
- <methodname>getMimeType()</methodname> returns the mimetype of a file. If more than one
- file was uploaded it returns an array, otherwise a string.
- </para>
- <example id="zend.file.transfer.introduction.informations.getmimetype">
- <title>Getting the mimetype of a file</title>
- <programlisting language="php"><![CDATA[
- $upload = new Zend_File_Transfer();
- $upload->receive();
- $mime = $upload->getMimeType();
- // Returns the mimetype for the 'foo' form element
- $names = $upload->getMimeType('foo');
- ]]></programlisting>
- </example>
- <note>
- <title>Client given mimetype</title>
- <para>
- Note that the mimetype which is given by the client is not seen as save input.
- Therefor the real mimetype of the file will be detected and returned instead of the
- mimetype sent by the client.
- </para>
- </note>
- <warning>
- <title>Possible exception</title>
- <para>
- Note that this method uses the fileinfo extension if it is available. If this
- extension can not be found, it uses the mimemagic extension. When no extension was
- found it raises an exception.
- </para>
- </warning>
- <warning>
- <title>Original data within $_FILES</title>
- <para>
- Due to security reasons also the original data within $_FILES will be overridden
- as soon as <classname>Zend_File_Transfer</classname> is initiated. When you want
- to omit this behaviour and have the original data simply set the
- <property>detectInfos</property> option to <constant>FALSE</constant> at initiation.
- </para>
- <para>
- This option will have no effect after you initiated
- <classname>Zend_File_Transfer</classname>.
- </para>
- </warning>
- </sect2>
- <sect2 id="zend.file.transfer.introduction.uploadprogress">
- <title>Progress for file uploads</title>
- <para>
- <classname>Zend_File_Transfer</classname> can give you the actual state of a fileupload
- in progress. To use this feature you need either the <acronym>APC</acronym> extension
- which is provided with most default <acronym>PHP</acronym> installations, or the
- <classname>UploadProgress</classname> extension. Both extensions are detected and used
- automatically. To be able to get the progress you need to meet some prerequisites.
- </para>
- <para>
- First, you need to have either <acronym>APC</acronym> or
- <classname>UploadProgress</classname> to be enabled. Note that you can disable this
- feature of <acronym>APC</acronym> within your <filename>php.ini</filename>.
- </para>
- <para>
- Second, you need to have the proper hidden fields added in the form which sends the
- files. When you use <classname>Zend_Form_Element_File</classname> this hidden fields are
- automatically added by <classname>Zend_Form</classname>.
- </para>
- <para>
- When the above two points are provided then you are able to get the actual progress of
- the file upload by using the <methodname>getProgress()</methodname> method. Actually
- there are 2 official ways to handle this.
- </para>
- <sect3 id="zend.file.transfer.introduction.uploadprogress.progressadapter">
- <title>Using a progressbar adapter</title>
- <para>
- You can use the convinient <emphasis>Zend_ProgressBar</emphasis> to get the actual
- progress and can display it in a simple manner to your user.
- </para>
- <para>
- To archive this, you have to add the wished
- <emphasis>Zend_ProgressBar_Adapter</emphasis> to
- <methodname>getProgress()</methodname> when you are calling it the first time. For
- details about the right adapter to use, look into the chapter <link
- linkend="zend.progressbar.adapters">Zend_ProgressBar Standard Adapters</link>.
- </para>
- <example id="zend.file.transfer.introduction.uploadprogress.progressadapter.example1">
- <title>Using the progressbar adapter to retrieve the actual state</title>
- <programlisting language="php"><![CDATA[
- $adapter = new Zend_ProgressBar_Adapter_Console();
- $upload = Zend_File_Transfer_Adapter_Http::getProgress($adapter);
- $upload = null;
- while (!$upload['done']) {
- $upload = Zend_File_Transfer_Adapter_Http:getProgress($upload);
- }
- ]]></programlisting>
- </example>
- <para>
- The complete handling is done by <methodname>getProgress()</methodname> for you in
- the background.
- </para>
- </sect3>
- <sect3 id="zend.file.transfer.introduction.uploadprogress.manually">
- <title>Using getProgress() manually</title>
- <para>
- You can also work manually with <methodname>getProgress()</methodname> without the
- usage of <classname>Zend_ProgressBar</classname>.
- </para>
- <para>
- Call <methodname>getProgress()</methodname> without settings. It will return you an
- array with several keys. They differ according to the used <acronym>PHP</acronym>
- extension. But the following keys are given independently of the extension:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>id</emphasis>: The ID of this upload. This ID identifies the
- upload within the extension. You can set it to the value of the hidden key
- which identified the upload when initially calling
- <methodname>getProgress()</methodname>. Per default it is set to
- <emphasis>progress_key</emphasis>. You must not change the ID afterwards.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>total</emphasis>: The total filesize of the uploaded files in
- bytes as integer.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>current</emphasis>: The current uploaded filesize in bytes
- as integer.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>rate</emphasis>: The average upload speed in bytes per second
- as integer.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>done</emphasis>: Returns <constant>TRUE</constant> when the upload
- is finished and <constant>FALSE</constant> otherwise.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>message</emphasis>: The actual message. Either the progress as
- text in the form <emphasis>10kB / 200kB</emphasis>, or a helpful message
- in the case of a problem. Problems could be, that there is no upload in
- progress, that there was a failure while retrieving the data for the
- progress, or that the upload has been canceled.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>progress</emphasis>: This optional key takes a instance of
- <classname>Zend_ProgressBar_Adapter</classname> or
- <classname>Zend_ProgressBar</classname> and allows to get the actual upload
- state within a progressbar.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>session</emphasis>: This optional key takes the name of a session
- namespace which will be used within <classname>Zend_ProgressBar</classname>.
- When this key is not given it defaults to
- <classname>Zend_File_Transfer_Adapter_Http_ProgressBar</classname>.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- All other returned keys are provided directly from the extensions and will not be
- checked.
- </para>
- <para>
- The following example shows a possible manual usage:
- </para>
- <example id="zend.file.transfer.introduction.uploadprogress.manually.example1">
- <title>Manual usage of the file progress</title>
- <programlisting language="php"><![CDATA[
- $upload = Zend_File_Transfer_Adapter_Http::getProgress();
- while (!$upload['done']) {
- $upload = Zend_File_Transfer_Adapter_Http:getProgress($upload);
- print "\nActual progress:".$upload['message'];
- // do whatever you need
- }
- ]]></programlisting>
- </example>
- <note>
- <title>Knowing the file to get the progress from</title>
- <para>
- The above example works when your upload identified is set to 'progress_key'.
- When you are using another identifier within your form you must give the used
- identifier as first parameter to <methodname>getProgress()</methodname> on the
- initial call.
- </para>
- </note>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 tw=80 et:
- -->
|