http://www.spotsec.com/blog Zend Framework Blogs
Feed Link
|
(SpotSec Networks Blog entries tagged 'Zend Framework') |
||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Extending Zend_Form for custom forms tip
Many people have created custom forms by extending Zend_Form and overriding __construct like so: class MyForm extends Zend_Form However, without looking at the api, you'd never see you could do it like this which is slightly cleaner: class MyForm extends Zend_Form |
||||||||||||||||||||||||||||||||||||||
DIRECTORY_SEPARATOR is not needed!
OverviewOne of PHP's misconceptions is that in order to write portable code, the DIRECTORY_SEPARATOR constant is needed for all folder paths. An example of this is in require's. require_once(MY_PATH . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'my.php'); The alternativePHP is smart enough to handle all paths that use a forward slash '/' on all platforms (that means windows). Using a forward slash instead of the directory separator constant where possible will make your code more readable. Zend Framework uses this method on all of its require's. /** After running a few tests and speaking to several people, it seems that it is perfectly fine to take this alternative. For most code, as long as you are using the forward slash '/' not the windows back slash '\' portability is guaranteed. Why have a constant?The constant is particularly useful because paths given by php use the native system's directory separator. The constant is particularly useful if you need to do some path mangling or exploding etc.. That's allWhile I am just giving out my opinion here as I find that the DIRECTORY_SEPARATOR use can go out of hand, it is up to you to decide. Please provide feedback on what you think ;). References
|
||||||||||||||||||||||||||||||||||||||
|
Zend Framework 1.5 PR - Development Moves On!
Whoo! With the release of Zend Framework 1.5PR, the feel of the framework moving forward starts to come back. Some things to look for in this release are Zend_Form, Zend_Db and Zend_Layout as they play an important role in the framework. Listed below are some additional features posted by Wil Sinclair :
Note for Naneau : It's been 4 months since you've posted... :( |
||||||||||||||||||||||||||||||||||||||
Extending Zend_Controller_Action and keeping init()
OverviewThere have been quite a lot of requests about how to extend Zend_Controller_Action in #zftalk lately, so I figured I'd post something to reference to. So what's so hard about extending Zend_Controller_Action? Nothing, it is just that for some odd reason people resort to overriding init() or calling parent::init() (I assume your too lazy to open up Action.php to grab the __construct() params ;) ). Basically the benefit of doing it the correct way allows you to use init() in your extended controller without calling parent::*. Yes, I am that lazy... Library Directory StructureOne of the other things people have asked about when creating custom classes for ZF that are reusable is where to put them. While they can be put anywhere and there is not a specified convention, I usually put them in my own namespace in a directory layout similar to Zend Framework. It is also simpler because extended classes mirror the ZF structure which make it easier for other developers to find.
The Coderequire_once('Zend/Controller/Action.php');Done!Simple eh? and all you had to really do is open up Action.php to read or the API docs to find out how (but I assumed you googled.... cheater). |
||||||||||||||||||||||||||||||||||||||
Zend Framework BaseUrl View Helper
Overview
The placeholder helperThis helper, released as part of the new view enhancements in 1.5, acts similar to the registry. We can set the baseurl into it from the bootstrap and it will be available where we need it whether it is in the layout or view scripts. // Bootstrap Retrieving the variable from a view script isn't that hard either... (plus the fact that it won't be destroyed if someone calls $this->clearVars()) echo $this->placeholder('baseurl')->baseurl;The helper
src="baseUrl(); ?>/images/foo.png" /** |
||||||||||||||||||||||||||||||||||||||
|
Integrating Doctrine ORM with Zend Framework
Overview
Including Doctrine
Bootstrapping Doctrine
/** Setting up a connectionModels in Zend FrameworkIntegration ClassesThese are integration classes which make using Doctrine with ZF much more seemless. Currently the ones I have posted are untested. SpotSec_Loader_Autoload_DoctrineAllows registering the autoloader using Zend_Loader::registerAutoload('SpotSec_Loader_Autoload_Doctrine');. This one's just for you integration purists ;) SpotSec_Auth_Adapter_DoctrineAn authentication adapter similar to Zend_Auth_Adapter_DbTable SpotSec_Log_Writer_DoctrineA writer similar to Zend_Log_Writer_Db. It was backported from Doctrine_Log to work with Zend_Log. SpotSec_Sesssion_SaveHandler_DoctrineA Zend_Session save handler using Doctrine as a medium. Resources |
||||||||||||||||||||||||||||||||||||||
|
#ZFTalk Log Statistics as of November 07
|
||||||||||||||||||||||||||||||||||||||
Camel-Cased Controller/Action naming and Sub-Controllers
Overview
ZF URL MappingCamel-Cased modules, controllers or actions
Example
Directory structure
MyModule_MyPageController
Explanation
Sub-Directories in the controllers folder
SubController_IndexController
There you have it ;)
|
||||||||||||||||||||||||||||||||||||||
Creating custom routes with Zend Framework
The ProblemSo you have setup a nice application built with Zend Framework right? But then you realize that the urls are very, lets say, unfriendly...
Now what? You must of sat there pondering on your choices and came to the conclusion that you can either accept "http://yoursite.com/account/auth/login" or demand "http://yoursite.com/login". The SolutionCustom routes! Hidden in the documentation of Zend_Controller is the delightful juices of Zend_Controller_Router_Rewrite. Rather than me explaining it, here is an excerpt of what it does: Zend_Controller_Router_Rewrite is the standard If you want to understand more about routing, I strongly suggest that you read the whole section and try creating some example routes as it does help. Types of routesCurrently there are four routes with one being the default routes under the name 'default' (Remember there is a removeDefaultRoutes function just in the unlikely case you want to remove them).
Zend_Controller_Router_RouteLets say we want "http://yoursite.com/login" with the ability to do "http://yoursite.com/login/SpotSec" to map to "http://yoursite.com/accounts/auth/login". First in the bootstrap we need to get the router object. It is accessable through the FrontController via: $frontController = Zend_Controller_Front::getInstance(); Next, lets create the route: $route = new Zend_Controller_Router_Route('login/:username/*', array('module' => 'accounts', // Add it to the router Now lets break down the route definition. In "login/:username/*", :username refers to anything provided after "login" aka "/login/SpotSec". It's a shortcut to doing "/login/username/SpotSec". "SpotSec" can be retrived in the controller via $this->getRequest()->getParam('username'); The asterisk * refers to any key/values that may be provided ("/login/SpotSec/key/value/key/value"). Simple eh? Next is the array of defaults. This array defines where the route should map to and what the default variables such as "username" equal. It also defines if variables like ":username" in the url are optional or not. If 'username' => null was not provided, "http://yoursite.com/login" would not match and you would get a 404 error, but if 'username' => null was provided, "http://yoursite.com/login" would match. Finally, the last array is optional, but it is useful when you want to make sure in "login/SpotSec" that SpotSec is a string or a numeric value. The format of this array is 'key' => 'regex'. NOTE: This array was just thrown in for example and I have not tested it. The result? http://yoursite.com/login || http://yoursite.com/login/SpotSec || http://yoursite.com/login/SpotSec/lang/en Using Zend_Config to Define RoutesSo you've figured out how to define simpe routes in php now right? But you then realize that this could get tedious right? The solution, moving php defined routes into ini or xml config files. Just because I am an xml fan and the manual has an ini example, I will show you the xml version. Here we setup the bootstrap: // Router config Now lets see the xml version of the route example above (Remember if you copy and paste this, the xml head is missing): WHOO, Naneau is a monkey!That's all for now, for part 2, we'll get into the regex route. Useful References |
||||||||||||||||||||||||||||||||||||||
|
Zend_Validate StringEquals implementation
It's a little wierd that people tend to miss the part in the manual that says Zend_Validate_StringEquals is hypothetical, so we see many people asking where it is. There is a Zend Framework test case here and my own implementation below. There are several ways to not use the StringEquals validator though, one is Zend_Validate_InArray(). $validators = array( A little strange, but it does work the same way the stringEquals validator does :/ /** |
||||||||||||||||||||||||||||||||||||||
|
Zend_Json Tutorial >_< (Are you kidding?)
Encoding to json Zend_Json::encode(array(‘a’)); Decoding from json Zend_Json::decode($json); |
||||||||||||||||||||||||||||||||||||||
Zend_Auth and Zend_Auth_Adapter_DbTable Tutorial
OverviewOne of the many tasks that almost every application has to deal with is authentication which defined by the Zend Framework manual as: Determining whether an entity actually is what it purports to be (i.e., identification), based on some set of credentials. Authorization, the process of deciding whether to allow an entity access to, or to perform operations upon, other entities is outside the scope of Zend_Auth. For more information about authorization and access control with the Zend Framework, please see Zend_Acl. While Zend_Auth and Zend_Acl are closely related, this article will only concentrate on Zend_Auth and it’s database table adapter (Zend_Auth_Adapter_Db_Table). It probably should handle the Authorization side of things, but for no, all I'll say is let Zend_Acl figure out if the user is "logged in" or not... Two ways to use Zend_AuthAuthenticating directly through the adapter will only verify if the user has the correct credentials while authenticating through Zend_Auth will effectively “log in” the user by setting the user’s identity (username or user row object) to Zend_Auth’s storage (Normally the session). Authenticating through the adapterIn occurrences where you would want to quickly check if a user’s credentials are valid and the persistence of the identity is not needed, authenticating through the adapter is the easiest way. ![]() // Setup adapter Authenticating through Zend_AuthWhen authenticating through Zend_Auth, it will take care if identity persistence. ![]() (Yes, I know what's wrong here...) // Get a Zend_Auth instance Checking if a user is logged inif (Zend_Auth::getInstance()->hasIdentity()) {Log out a userZend_Auth::getInstance()->clearIdentity(); // Simple eh? Example demo applicationOk, that was a bad tutorial, but hey here's my example application for you to check out... Since I wrote it, expect it to be biased and probably poorly coded as I quickly put everything together. It includes Zend Framework so just place the zend_auth-tutorial folder in your document root and browse to it (After configuring the db in config.xml ofcourse ;) ). |
||||||||||||||||||||||||||||||||||||||
|
Zend Framework Pastebin example app (SpotSec Paste)
Since Zend Framework 1.0 has come out, there have been many people looking for a simple hello world example application that does slightly more than hello world, so here it is, "SpotSec Paste". It is a quick and dirty pastebin application based on http://www.paste2.org's simple functionality. This quicky, while it doesn't have all the best practices I would like, does show how to use several of ZF's components and a few other tricks that make life simpler. While it currently lacks many features of an actual pastebin site, this example application should be enough for those looking for an example to figure things out. Hopefully you will figure out what's good practice and what's bad from the code I wrote O_O. There are a few things that I think are missing from Zend Framework that should be included eventually, one of them is a baseUrl helper. Since I believe that global view variables are bad practice, wrapping baseUrl into a helper just seems right. Another helper I was thinking of implementing was a view registry of some sort to offload the usage of global view variables to a registry to unclutter the view. Some limitations are that it uses geshi and geshi does not handle large code snippets very quickly. The solution would be either to cache the output with a static html view helper or just a plain caching view helper. Anyways, maybe some other day. . . Other known problems is a css issue in opera, but I'm also too lazy to fix that.... BSD licensed DemoDownload |
||||||||||||||||||||||||||||||||||||||
|
Zend_View_Helper_DeclareVars (Error Notice: key does not exist)
Some times the most simplest solutions to problems tend pass us by The declareVars(): The $this->declareVars( Why is this useful? It is useful when working with forms and setting form values. <?php $this->declareVars('email', 'country', 'optIn'); ?>
|
||||||||||||||||||||||||||||||||||||||
|
Zend Framework Controller Modules? Huh?
Day to day, I tend to lurk in #zftak monitoring the discussions and occasionally I myself enter into discussions that wakes up the whole chat room because everyone has a different opinion on some subject. Today it seemed like most people could not agree on a standard directory layout, while others when off in a tangent about panda bears. This issue came up mainly because of what is specified in the Zend Framework manual. The manual does not exactly get to the point (or atleast the good stuff), so most people end up either creating a list of modules and adding them manually to the frontcontroller. The other issue was the conventional modular directory structure section in the manual: docroot/ Several people argued that since this is the way it was specified in the manual placing modules in the root of the application folder was recommended /** As shown here, having modules within a modules folder seems logical and allows the use of addModuleDirectory() which dispite of it's name, accepts a path to a directory containing modules. So it seems, "it's not a bug in the code, it's a bug in the programmer"... (or perhaps the layout of the manual for that page isn't very skim-reader friendly as the information introduced is built on by the more important info specified at the bottom...) |
||||||||||||||||||||||||||||||||||||||
|
Zend_Log Syslog Writer (SpotSec_Log_Writer_Syslog)
Logging is something most applications do, logs help keep everything in order and the feeling of big brother standing right beside you. Zend_Log allows a php developer to easily implement logging into their application with the use of 'writers'. One writer I found to be missing from the Zend_Log component was a Syslog adapter which I thought was part of the Zend_Log rewrite proposal, but upon checking the proposal, it appears I was wrong. Anyways, I created a quick and dirty syslog writer for Zend_Log. This is by no means production ready as I have not tested it well enough, nor does it have the features that most would want. (I'm not sure, but tinymce tends to escape things that I wish it wouldn't so the code may have some errors. Oh anything labeled SpotSec Framework is actually bsd licensed except I never got around to changing the template. ) /** |
||||||||||||||||||||||||||||||||||||||
|
What is Zend Framework View Exception error.phtml?
Well, I was checking google sitemaps the other day and I saw one search engine query that just made me laugh uncaught exception zend_view_exception with message script "error error phtml" not found in path Apparently there are a few people who still get blind sighted by the ViewRenderer (VR) action plugin and the ErrorController (ER) controller plugin which were quietly slipped in for Zend Framework 1.0 RC1. During that time it caused a stirr because it was unexpected, but most developers who have been using ZF since the 0.x.x series have learned to embrace VR. Anyways for those who searched and came here because of those mysterious view script exception errors like index.phtml or error.phtml, the solution is to create that file in your view/scripts/controller folder. Reading up on the VR and the ER documentation should tell you much more than I can. |
||||||||||||||||||||||||||||||||||||||
|
The basics of Zend_Layout (ahem, Xend_Layout)
Zend_Layout has made it into core as of now. This tutorial is out of date and only relates to the prepoposal form of Zend_Layout. In other words, do not use it! Akrabat has beaten me to an updated tutorial: http://akrabat.com/2007/12/11/simple-zend_layout-example/ Overview
Let's Start
/**
// Basic Usage, using a previously configured layout, throws exception if non existent
public function __construct($name, $action, $controller, $module = 'default', Array $params = array())
// Advanced Usage (adding a request)
/*?php*/ body: $this->content; > Disabling Zend_Layout
// Disable VR
Other Resources
|
||||||||||||||||||||||||||||||||||||||
|
Zend Framework Example Project (coderepo)
Well, it's been a few weeks after the release of Zend Framework's RC2, and it has given developers enough time to start settling in with a stable api. With the coming release of RC3 and hopefully less bugs instead of introducing new ones, RC3 will bring more converts to Zend Framework. While the ZF team is rushing to push 1.0 GA out the door, there are still bugs in ZF, there are a few that I spotted and reported, but there are more that I haven't. With the upcoming stablish api, I think it is about time that we start a large example application that other users can learn from. Looking around and from requests on #zftalk, I found that the community is in serious need of a ZF code repository because much of the code that developers write for their own use with ZF is quite reusable and helpful for others. In a blog by naneau, he explains the differences of view helpers, action helpers, and controller plugins. These "snippets" solve small repetitive tasks that a developer will go through while writing their applications. So why not share snippets with other developers, this way small repetitive tasks can be eliminated. Enough about what the example project is, lets talk about how we are going to do this. Since I've decided this project should be an example application that new comers to Zend Framework can have a look at and possibly 'steal' code or styles from, the ZF-CodeRepository is going to be treated as a community project. Development will be open, anyone who feels that they want can improve the project can, but all code should be up to ZF standards. Why?, this is in order for others to learn the "correct" way of doing things (ok, it might be my way occasionally). This is because I've seen several projects based on ZF and the code was just not up to standards. While they worked, the implementation was horrible. As for information, here it is: Database design*Features overview**draft |
||||||||||||||||||||||||||||||||||||||
|
Zend Controller Acl Plugin
The usage of Zend_Acl described on the manual are fairly vague at the moment, but most experienced PHP programmers would find their way to creating a controller plugin. Out of laziness, SpotSec_Controller_Plugin_Acl was born because I wanted an easy way to implement Zend_Acl. While Zend_Auth is not related to this plugin, the plugin leaves this up to the developer when implementing the acl plugin's adapter. While I will not go through how to use Zend_Acl, basic usage of this is that a developer would extend SpotSec_Controller_Plugin_Acl_Adapter_Abstract to work with their setup. Usage // Personal extended Acl Adapter that forwards to a login page on permissions denied /** /** |
||||||||||||||||||||||||||||||||||||||
|
Zend Model Loading (ModelLoader)
ModelLoader is now a proposal under Ralph Schindler located at Zend_Controller_Action_Helper_ModelLoader Normally models are loaded through require_once() or Zend_Loader::loadClass() with painfully long paths similar to "module/models/Model.php" or "module/models/controller/Model.php" and more likely "../models/controller/Model.php". After a few discussion on #zftalk with ralphschindler, SpotSec_Controller_Action_Helper_ModelLoader came to existence. ModelLoader does exactly what the name says, it makes loading models one step simpler by determining the path to the models folder so all you have to do is specify the model's class name. If you are using the conventional modular directory structure then ModelLoader is already setup and ready to go. If you are not then you can setup ModelLoader using __construct(); Usage: $this->_helper->ModelLoader('UserModel');/** |
||||||||||||||||||||||||||||||||||||||
|
#ZFTalk is growing
After the seed was planted, #ZFTalk seems to be growing steadily every day. It was displayed on DevZone and on PHPDeveloper, since then it has been replicated by many sites. Perhaps it's time you joined in .irc://irc.freenode.net/zftalk |
||||||||||||||||||||||||||||||||||||||
|
Finally a Zend Framework IRC Channel
So anyways a few of the folks over in http://zfforums.com decided there was a need for a Zend Framework irc channel, but there was no official one around so here it is the unofficial: #zftalk on irc.freenode.net Visit the homepage: http://www.zftalk.com |
||||||||||||||||||||||||||||||||||||||
|
Sigh, PHP including latency
|
||||||||||||||||||||||||||||||||||||||
|
Zend Controller NoRoute Plugin
NOTE: The NoRoute Plugin has been deprecated since 1.0 RC1 in favor of the Zend_Controller_Plugin_ErrorHandler
/** |
ZF Home Page
Code Browser
Wiki Dashboard


. This is not actually the case since an application consists more than just an application folder with modules in it, it consists of configs, jobs, etc... If they read the whole page of the conventional modular directory section they would have seen the goodies...
) 
.