How to use Zend’s Action Helpers, well, everywhere.
Well, this is certainly out of the ordinary, both for me and you. I really never wanted to see "technical" posts on this blog, but I'll make an exception this one time. I always find myself thanking the random blogger who "solved" my problem on the first google search result. Maybe this will help someone.
I had a great opportunity working with the amazing eng team at Dipity. It's a great step moving from "hello-world-college-programming" to be thrown into an infant product and watch it grow. It was great to watch the the entire architecture get built from the ground up. To this day, as I'm sure Ben agrees with me, it's is my theory that no one who uses PHP know what the hell they are doing, including me.
(for proof go to php.net and look at examples) I think it was a huge advantage to watch a "MVC" get built without ever knowing what "MVC" even meant. I recently started diving into the Zend framework for a couple weeks now and have found a similar conclusion after searching for help on certain topics. It seems like a lot of people just don't really know whats going on.
In Zend, common functions, classes, and utilities are known as "helpers." Think of it (but don't, because it's not) like a class with a bunch of static methods you need to call over and over again. To make things a little more confusing zend has two types of helpers, one that is specific to views and the Zend_View object, and the other to Zend_Action_Controller objects. What's the difference you ask? Plenty. First of all, their contexts use are very different, or should be. View helpers are supposed to be common utils to help with layout tasks. Possible view helpers could include encoding, url formatting, field validation, etc. If you find yourself building view helpers that begin to tinker with business logic and models, you are most likely then not abusing the MVC model.
Here is a sample view helper
<?php class Zend_View_Helper_BaseUrl { function baseUrl() { $fc = Zend_Controller_Front::getInstance(); return $fc->getBaseUrl(); } }
Pretty straightforward when it comes to view helpers. When you find yourself in a template file and you need to call a helper simply
<a href="<?=$this->getBaseUrl()?>"Base Url</a>
A little more confusing though, is understanding how to successfully utilize the Zend's action helpers. Think of them similar to view helpers, but in in order to solve the business logic/model layer of the framework. Below is the same helper, but in action helper form. Now sure, this is actually a bad example of an action controller because I'm doing exactly what I told you not to do. You shouldn't be dealing with markup stuff in your business logic. But pretend below was a utility function that helped you solve some problem you use across many of your models.
<?php /** * "Global" Action Helpers for site wide use. * These helpers are function which are used frequently site wide * for use in action controllers. Many may look similar to view helpers * * @uses Zend_Controller_Action_Helper_Abstract * @author rromanchuk * @example Zend_Controller_Action->_helper->AppUrl(); */ class Global_Helpers_AppUrl extends Zend_Controller_Action_Helper_Abstract { /** * Return the base url * @return String $app_url */ public function appUrl() { $appInfo = Zend_Registry::get('appInfo'); return $appInfo['fb_url']; } /** * Method the helper broker runs when called directly within an action controller * @return String $base_url */ public function direct() { return $this->appUrl(); } }
The helper above give you the ability to call this utility object within the controller by calling the helper broker like
$baseUrl = $this->_helper->AppUrl()
I have to mention, I am leaving a lot of the details out, but I am assuming you are already familiar with Zends Reference on action helpers.
The problem with action helpers is that in this scenario, you can can only call these helpers inside an action controller class because you do not have access to the _helper object anywhere else. It's sloppy to think you can pass a Zend_Action_Control as $this to a model class, and besides, you will run into fatal errors with access restrictions. Zend does offer you access to these 'static' helpers with the the broker. For instance you could retrieve the helper by calling
Zend_Controller_Action_HelperBroker::getStaticHelper('appUrl');
Uggghhhh, but who wants to write that every time you needed to use a util method? I don't! So I came up with what I thought to be a little more elegant of a solution to avoid forcing the programmer to always have to deal with the helper broker for your site-wide util methods.
abstract class ExternalClass { protected $html; abstract function getHtml (); public function __call($method, Array $arguments = array()) { error_log("Loading action helper $method"); $helper = Zend_Controller_Action_HelperBroker::getStaticHelper($method); return $helper->direct($arguments); } }
By utilizing php's magic method __call() we can now call any action helper by extending this base class (or not) by simply calling
$this->appUrl()
Wooo! we can now break the chain from Zends_Really_Long_And_Annoying::VerboseNameSpacesLikeThis();
![[Most Recent Quotes from www.kitco.com]](http://www.kitconet.com/charts/metals/gold/t24_au_en_usoz_2.gif)
LOL() ?>
oh wow i commented using fake php code and looks like I typed in enough correctly to be processed by the server
i guess that speaks to the “no one knows what they’re doing” claim, huh?
If by “processed by the server” you mean your comment was stripped to prevent sql injection, then yes.
Hello
I have one question about this excellent post:
Where in the Zend MVC project do you declare your abstract ExternalClass? I can’t get it working the way you explain it here
Thanks in advance!
“If by “processed by the server” you mean your comment was stripped to prevent sql injection, then yes.”
Boom. Roasted.
nice article about zend helper…I’m new in Zend and always want to learn its best practices.