Sunday, October 27, 2013

Automatically Serialize All View Variables

No question here, just thought I'd share a solution to a problem I needed to solve.

I'm working on a decoupled application where the back-end is all CakePHP and the front-end is all Javascript. The front-end communicates with the back-end as a RESTful API. I could write a handful of posts in here about some of the problems I ran into, but right now, I just want to share a trick I developed with serializing view variables.

I use jQuery AJAX functions to get json from CakePHP. I got tired of writing this all over my controllers:

$this->set('_serialize', array('omg', 'so' 'many', 'view', 'vars'));

So I decided to automatically serialize all my view variables in my app controller's beforeRender callback. (beforeRender is called after all the application logic is finished, right before the view is rendered. Good name for it huh?)

// AppController.php
public function beforeRender(){
// When setting _serialize, you pass in a list of variable names.
// array_keys($this->viewVars) returns an array of the names of the view variables 
$this->set('_serialize', array_keys($this->viewVars));
}

That works, but if I need a way to ignore some view variables, I would have to do something a little more elaborate.

// AppController.php
public function beforeRender(){
// When setting _serialize, you pass in a list of variable names.
// array_keys($this->viewVars) returns an array of the names of the view variables
$viewVars = array_keys($this->viewVars);
 
// I include _serialize to prevent the possibility of a _serialize inside another _serialize 
$varsToIgnore = array('_serialize', 'debugToolbarPanels', 'varThatOnlyAppliesToBackEnd');
 
foreach($varsToIgnore as $varToIgnore){
// Might be a better way of doing this, but it works and seems safe
// in_array checks if a value exists in an array
// unset removes an array or array index in this case
// array_search returns the index of where a value is found 
if(in_array($varToIgnore, $viewVars)) unset($viewVars[array_search($varToIgnore, $viewVars)]);
}
 
// Reindex the viewVars array after removing variables from above
// I don't know if this is really necessary, but I did it anyway.
$viewVars = array_values($viewVars);
 
$this->set('_serialize', $viewVars);
}

My beforeRender method is getting a little too long for my liking, so I decided to clean it up a bit, by moving the variables to ignore into a private property and the logic to serialize the view variables into its own private method.

// AppController.php
// A shorter name would be easier to type
private var $viewVariablesNotToSerialize = array('_serialize', 'debugToolbarPanels', 'varThatOnlyAppliesToBackEnd');

public function beforeRender(){
$this->__serializeViewVars();
}

private function __serializeViewVars(){
// When setting _serialize, you pass in a list of variable names.
// array_keys($this->viewVars) returns an array of the names of the view variables
$viewVars = array_keys($this->viewVars);
 
foreach($this->__viewVarsNotToSerialize as $varToIgnore){
// Might be a better way of doing this, but it works and seems safe
// in_array checks if a value exists in an array
// unset removes an array or array index in this case
// array_search returns the index of where a value is found 
if(in_array($varToIgnore, $viewVars)) unset($viewVars[array_search($varToIgnore, $viewVars)]);
}
 
// Reindex the viewVars array after remove variables from above
// I don't know if this is really necessary, but I did it anyway. 
$viewVars = array_values($viewVars);
 
$this->set('_serialize', $viewVars); 
}

I hope someone finds this useful.

Matt Bowden
Web Application Developer
Skybrick

--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP
 
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/groups/opt_out.

No comments: