Search code examples
phpzend-frameworkpartialzend-view

Zend View array variable inside a partialLoop


Here is the code in my controller:

$this->view->myArray = array();
$this->view->test = "";
$out = $this->view->partialLoop('tab/partial.phtml', $data);

echo $this->view->test;  // Output: This works
echo count($this->view->myArray); // Output: 0

And the partial partial.phtml:

$v->test = $this->partialLoop()->view;

$v = "This works";
echo $v->test;  // Output: This works

$v->myArray[] = "hello";
echo count($v->myArray); // Output: 0

I don't think that accessing view variables from a partialLoop is a wonderful idea. That aside, why doesn't it work for my array variable?


Solution

  • it doesn't work because you don't have access to the view variables in the partial. You have access to the data you pass to the partial.

    $out = $this->view->partialLoop('tab/partial.phtml', $data);
    

    This line of code would have access to the information contained in $data.

    So this code in your current partial is basically meaningless:

    $v = $this->partialLoop()->view; //you choose to assign view data to the partial, and I don't think it's working as expected. 
    //By not passing any args to the partial you have at least some access to the view object.
    
    $this->view->test = "This works";//assign data to view locally
    echo $v->test;  // you seem to be echoing out locally assigned data
    
    $v->myArray[] = "hello";//you didn't assign this to the view
    echo count($v->myArray); // myArray probably doesn't exist in this context or dosen't work as expected. If you make this an associative array it might work.
    

    I don't think I've ever seen partials used in quite this manner before. The point of the partial is to establish a different variable scope for a specific portion of the view.

    The partial and partialLoop are view helpers so the only action you need to take in your controller (data may be or come from a model as well) is to make available any data you want to use in your partials as well as any data you want available in your normal view scope.

    //in a controller
    public function userAction() {
        $model = Application_Model_DbTable_User();//Table columns = id, name, role
        $this->view->partailData = $model->fetchAll();//assign data to view that we want to use in partial, should be an array or object.
    }
    
    //in a view script
    <?php 
    //pass the path to the partial as the first arg and the data to be displayed as the second arg
    echo $this->partialLoop('/path/to/partial.phtml', $this->partialData);
    //we could pass data explicitly as well
    echo $this->partial('/path/to/partial.phtml', array('id'=>1,'name'=>'jason','role'=>'user'));
    ?>
    
    //now for our partial.phtml
    //this could be used a simple partial or as a partialLoop
    <p>My name is <?php echo $this->name ?>.</p>
    <p>My data file id is <?php echo $this->id ?>.</p>
    <p>My access control role is <?php echo $this->role ?>. </p>
    <!-- name, id and role would be column names that we retrieved from the database and assigned to the view -->
    

    To use a partial or partialLoop you need to pass an array of some type or an object that implements toArray().

    [EDIT]

    Clean up your code your still in left field.

    //controller code
    $this->view->myArray = array();
    
    //view code
    <?php $v = $this->partial()->view ?> 
    <?php $v->myArray[] = 'newName' ?>
    <?php Zend_Debug::dump(count($this->partial()->view->myArray)) ?>
    
    //my output =
    
    int(1)
    

    I don't seem to be able to pass the view any further then this, if I assign to an actual partial script and attempt to output the view object errors are thrown:

    //my view again
    <?php echo $this->partial('partial.phtml', $this->partial()->view) ?>
    //This and attempts similar result in the error
    /*Catchable fatal error: Object of class Zend_View could not be converted to string in E:\www\home-local\application\views\scripts\partial.phtml on line 1*/
    //when the partial.phtml looks like
    <?php echo $this />
    
    //however when I access the data available in the view
    <?php echo $this->myArray[0] ?>
    
    //the result works and the output is   
    newName 
    

    it looks like an empty partial() (partialLoop()) call will give you access to the view object, when you already have access to the view object. If you leave the scope of the view object you will have only the access available to your current scope as provided by __get() and __call().

    I hope I was able to explain this enough to help.