Issues

ZF-7976: Notice at Zend/File/Transfer/Adapter/Http.php

Description

I got the following warning when working with a Zend_Form_Element_File in a trivial form:


Notice: Undefined index: CONTENT_LENGTH in /usr/local/php/share/Zend/File/Transfer/Adapter/Http.php on line 124

The line 124 we have:


// Workaround for a PHP error returning empty $_FILES when form data exceeds php settings
if (empty($this->_files) && ($_SERVER['CONTENT_LENGTH'] > 0)) {

Maybe a simple array_key_exists() or isset() before the if might solve this notice.

Comments

When there is no CONTENT_LENGTH available then you have a web-server problem. It should always be available as long as $_POST is here and you received data from a form.

And when POST does not exist you can not have a active upload.

Feature added.

The HTTP protocol defines that CONTENT_LENGTH must be available in POST requests.Note that a missing CONTENT_LENGTH shows a broken web server. So you should install the newest release of your webserver to get rid of this problem.

The notice did not appeared when trying to submit the form, but after the form was rendered.

I created a form using a class:


class Form_Upload extends Zend_Form
{
    public function init()
    {
        $this->addElement('file', 'upload', array(
            'required'    => true,
            'filters'         => array(...),
            'validators' => array(...)
        );

        $this->addElement('submit', 'submit', array('label' => 'Upload it!'));
    }
}

Then I just created a form object in controller and injected in view:


class UploadController extends Zend_Controller_Action
{
...
    public function indexAction()
    {
        $this->view->form = new Form_Upload();
    }
...
}

Finally, I just rendered in my view...


...
echo $this->form;
...

... and got the notice as described above.

Thanks

Which means that you are calling receive() when you just display the form.

Receive must only be called when a form has been provided, not when it's being displayed. The manual describes how the correct usage is.

Normally you have to do something like:


if ($form->isPost($_POST)) {
    $element->reveice();
}

When you are having problems with form itself then please write into the mailing list.

Which means that you are calling receive() when you just display the form. I am not calling {{receive()}} - as showed in the code above.

A deeper look at my code and I noticed that I am calling {{isValid()}} without POST data in the request, generating the notice as described.

Anyway, as defined in PHP manual section:

{quote} ...NOTICE messages will warn you about possible bugs in your code. For example, use of unassigned values is warned. It is extremely useful to find typos and to save time for debugging. NOTICE messages will warn you about bad style. {quote}

In my opinion, the component might handle this notice.

Just for the records, the Zend_Form doesn't have a {{isPost()}} method. I believe you mean:


if ($this->getRequest()->isPost()) {
    $element->receive();
}

This verification might be defined within the component as well.

*) The code above does not show anything... there is no file upload done you just gave the code for rendering... not more not less.

*) The component does handle the notice. Otherwise this issue would not have been fixed for the next release.

*) Why and how should Zend_File_Transfer verify if the controller is called by post or not ? There is no connection between this components. Additionally Zend_File_Transfer can be called with Put, Delete, Ftp, Webdav or any other protocol. It is not fixed to Post. So this would not work.

*) Precisely, it shows that nothing has been done than creating and rendering the form.

*) Cool.

*) Any component can introspect the request through Zend_Controller_Front:


// Gets a front controller singleton instance
$front       = Zend_Controller_Front::getInstance();

// Now you have the request
$request = $front->getRequest();

In my opinion, there is a connection between Zend_File_Transfer_Adapter_Http and Zend_Controller_Request_Http, as Zend_File_Transfer_Adapter_Http uses an HTTP request as data source. Additionally, you can use the Zend_Controller_Request_Http {{isGet()}}, {{isPost()}}, {{isDelete()}} and {{isPut()}} methods ensure that the request holds the correct data - only for HTTP adapters.

Thanks.

Line 124 you gave as error is from the isValid method. This method is only called when you call isValid on the form.

Your code does not call this method, so there are things missing which you did not gave. That's what I mean with missing parts. The code you gave does not call isValid, so the notice itself is not thrown just by the code you gave.

And no, we will not limit Zend_File to Zend_Controller_Request_Http. Beside of the BC break this would mean, it would also add a limitation which is not necessary.

Actually I didn't proposed a limitation, I proposed just an additional validation, to handle a potential problem explicitly and avoid wrong usage. I don't see how this verification could limit others adapters.

Anyway, the subject of the issue was the notice message and it seems to be solved, thanks for your time.