ZF-6973: Zend_CodeGenerator_Php_Property can't be an Array

Description

Example:


new Zend_CodeGenerator_Php_Property
(
    array
    (
        'name'         => '_myProperty',
        'visibility'   => 'protected',
        'defaultValue' => array('value1', 'value2')
    )
)

out in the class

protected $_myProperty = 'array('value1', 'value2')';

So there is "extra" quotes

Comments

It can not be used with an Array?

Add an example

I can confirm this

When calling e.g.


$class->setProperties(array(
        array(
            'name'         => '_dependentTables',
            'visibility'   => 'public',
            'defaultValue' => array('Test'),
        )));

the only thing that is generated is


    public $_dependentTables = 'Array';

When looking at the source code


    public function generate()
    {
        $name         = $this->getName();
        $defaultValue = $this->getDefaultValue();
        if ($this->isConst()) {
            $string = '    ' . 'const ' . $name . ' = \'' . $defaultValue . '\';';
        } else {
            $string = '    ' . $this->getVisibility() . ($this->isStatic() ? ' static' : '') . ' $' . $name . ' = ' . ((null !== $defaultValue) ? '\'' . $defaultValue . '\'' : 'null') . ';';
        }
        return $string; 
    }

it is obvious that it just casts the Array to a string, without doing anything sophisticated. I would expect it to "parse through" the array doing something like


<?php

$array = array("test", 'test' => "test", "test", array("lalaal", "1234"));
echo parseValue($array) . "\n";

function parseValue($val)
{
    if ($val == null)
    {
        return null;
    }
    else if (is_array($val))
    {
        $entries = array();
        foreach ($val as $key => $entry)
        {
            $entries[] = '\''.$key.'\' => ' . parseValue($entry);
        }
        return 'array(' . implode(", ",$entries) . ')';
    }
    else
    {
        return '\''.$val.'\'';
    }
}
?>

I think I will implement it in my own ZF as a workaround for now. I don't know if there are any better (built-in?) solutions for this?


        return null;

should of course be


        return 'null';

Let me know if you consider implementing something like the above in the official ZF - by then, I have likely implemented "pretty indenting" in the function as well..

Fixed in r16344

Thanks a lot - from the code it looks like it became a little more complicated when pretty-printing etc. was needed :-)

Do you have a recommended way of having objects as part of the default value?

My workaround for now is something like:

$class->setProperties(array(
        array(
            'name'          => 'filters',
            'visibility'    => 'public',
            'defaultValue'  => array(
                new Zend_CodeGenerator_Php_Property_DefaultValue(array(
                    'value' => 'new Zend_Filter_BaseName()',
                    'type'  => Zend_CodeGenerator_Php_Property_DefaultValue::TYPE_NULL
                )),
                new Zend_CodeGenerator_Php_Property_DefaultValue(array(
                    'value' => 'new Zend_Filter_Int()',
                    'type'  => Zend_CodeGenerator_Php_Property_DefaultValue::TYPE_NULL
                ))
        ))));

I am "misusing" the TYPE_NULL for getting it to render the value without quotes.

Dang, what I wanted is actually not supported by PHP. Ignore my comment above for now..

Ha, yeah. Property default values can only be scalar, constant and null. You'd want to populate with real objects at construction time. Rule of thumb is that CodeGenerator produces valid PHP code, so it attempts to play by all the rules of the language.

-ralph