Issues

ZF-2526: Zend_Form_Element::getAttribs() returns an empty array

Description

I can't get Zend_Form's elements to render "title" attributes and it appears to be because Zend_Form_Element's getAttribs() method does not return attributes that have been previously set (while getAttrib() works fine). Here's how I reproduce the problem:


$options = array(
    'title' => 'my summary',
    'name' => 'username',
    'label' => 'Username',
);
$username = new Zend_Form_Element_Text($options);
var_dump($username->getAttribs());

Produces:
array(0) {
}

I suspect this is a new PHP bug (I use PHP 5.2.0-8+etch9), whereby declaring $this->$someprop does not give it any visibility and so this is why the reflection isPublic() test in getAttribs() fails incorrectly.

I've written the following patch which seems to correct the problem:


Index: incubator/library/Zend/Form/Element.php
===================================================================
--- incubator/library/Zend/Form/Element.php     (revision 7696)
+++ incubator/library/Zend/Form/Element.php     (working copy)
@@ -493,8 +493,11 @@
         $properties = $r->getProperties();
         $attribs = array();
         foreach ($properties as $property) {
-            if ($property->isPublic()) {
-                $attribs[$property->getName()] = $property->getValue($this);
+            if (! $property->isPrivate() &&
+                ! $property->isProtected() &&
+                ! $property->isStatic()
+            ) {
+                $attribs[$property->getName()] = $this->getAttrib($property->getName());
             }
         }

Comments

The code below takes Zend Framework out of the loop, and tests the problem directly.

Please try the code. Does anyone have the same output as me with myRuntimeProperty missing in the var_dump? If you do, I think Zend_Form_Element::getAttribs() will not work with your PHP version, and maybe I should raise it on bugs.php.net. Any comments appreciated.


<?php

class Test
{
    public $myDeclaredProperty = 1;

    public function __construct()
    {
        $this->myRuntimeProperty = 2;
    }

    public function getPublicProperties()
    {
        $r = new ReflectionObject($this);
        $properties = $r->getProperties();
        $publicProperties = array();
        foreach ($properties as $property) {
            if ($property->isPublic()) {
                $publicProperties[$property->getName()] = 
$property->getValue($this);
            }
        }
        return $publicProperties;
    }
}
echo 'Running ' . phpversion() . "\n";
$obj = new Test();
echo "Dumping object:\n";
var_dump($obj);
echo "Dumping public properties according to Reflection object\n";
var_dump($obj->getPublicProperties());

My output. Note myRuntimeProperty is missing in the second var_dump:


Running 5.2.0-8+etch9
Dumping object:
object(Test)#1 (2) {
  ["myDeclaredProperty"]=>
  int(1)
  ["myRuntimeProperty"]=>
  int(2)
}
Dumping public properties according to Reflection object
array(1) {
  ["myDeclaredProperty"]=>
  int(1)
}

Duplicates ZF-2518, already reported.

Resolved in r7708, using the same logic used in Zend_View_Abstract::getVars() (known to work in PHP >= 5.1.4)