Skip to content

Zend Framework: CRUD

Update, 2012-05-24: Fixed some typos and added the screenshot (eyecandy!).

I think it took me (or us) a couple attempts to get this right — let me introduce you to Zf_Crud, a CRUD controller for the Zend Framework.

What's CRUD?

CRUD is an acronym and stands for:

  • Create
  • Read
  • Update
  • Delete

A general purpose for CRUD are administrative interfaces — view records, create them, update them or delete them. Think of phpMyAdmin as a very general purpose CRUD interface. One you need some SQL-fu for.

In my experience, such interfaces are most likely or often the very last item on a project. Not too many people (myself included) like to build these interfaces primarily because we have build them before. They are necessary non-the-less: not everybody on a project is a developer and feels comfortable writing SQL queries into phpMyAdmin to get data out (or in).


Zf_Crud aims to provide you with an interface for any table possible — think of it as a phpMyAdmin more tailored towards your data and (thanks to Twitter Bootstrap and the Easybib_Form_Decorator) prettier!


Note: We haven't setup a PEAR package yet. I'll get to it soon, but feel free to submit a PR with a package.xml.


The only technical dependencies are PHP 5.3+ and the Easybib_Form_Decorator:

$ pear channel-discover
$ pear install easybib/Easybib_Form_Decorator

The other dependency is a working Zend Framework (1) application and an idea what you're doing.


To setup Zf_Crud, clone (or export) it into your local vendor library:

Our Zend Framework projects have the following structure:

  • app/modules/<module>/library/vendor

To export with git, just do the following:

$ cd app/modules/foo/library/vendor
$ git clone git:// ./Zf_Crud
$ cd Zf_Crud && rm -rf .git

Then check it into your own VCS.

If you don't have git (and cannot install it), get a download of Zf_Crud from Github.

Composer, you ask?

With the initial public release, we also added composer:

  "require": {
    "php": ">=5.3.0",
    "lagged/Zf_Crud": "0.5.1"


Working with Zf_Crud should be super-simple and easy!

In your module (e.g. foo), create a controller in app/modules/foo/controllers/AdminController.php.

use Lagged\Zf\Crud\Autoload as CrudAutoload;
use Lagged\Zf\Crud\Controller as CrudController;

require_once dirname(__DIR__) . '/library/vendor/Zf_Crud/library/Autoload.php';

class Foo_AdminController extends CrudController
    protected $model = 'Foo_Model_SomeTable';
    protected $title = 'My Interface';

Next, create a plain model using Zend_Db_Table_Abstract:

class Foo_Model_SomeTable extends Zend_Db_Table_Abstract
    protected $_name = 'some_table';

The (naming convention in ZF1 is not PSR-0 and a little weird. In case it's not obvious: the) model should live in: app/modules/foo/models/SomeTable.php.

Last but not least: Zend_Db_Table means RDBMS. Zf_Crud expects a Zend_Registry-key called dbAdapter to work. If your's is called differently, skip to the "Convention over Configuration" section.

Anyway — once these two files created (and assuming the rest is setup correctly), you should see something like the following:


Convention over configuration

I'm a fan of convention over configuration and it's the approach we selected when we build Zf_Crud.

The idea is that it should work out of the box without setting up a huge application.ini or DIC, in case you want to tinker with it when you're up and running, here is how.

Since you're extending from the Lagged\Zf\Crud\Controller, this controller has a few configuration options. Configuration is probably too advanced since these are essentially a bunch of class-properties you can overwrite in your class or via init():

// setup here
class Foo_AdminController extends CrudController
    protected $model = 'Foo_Model_SomeTable';
    protected $dbAdapter = 'db';

Some of the gems are:

  • $where: a WHERE-clause for the data query
  • $order: column to order by
  • $hidden: hide these columns from display
  • $count: number of items per page


We've been using this code for a couple months now for various items. We recently tagged an early 0.5.1 which suggests that this code is still a WIP and a moving target. The configuration bits are not too great elegant yet. So there are a lot of rough edges to be aware of.

The bottom line is that Zf_Crud has been good for us since it allows us to take the pain out of building administrative interfaces. In most cases it's setup in an hour tops and then we can move on to build something more interesting than a couple forms and views to display and edit data.

If you have anything to add — comments and pull-requests welcome!

Expose services via an ssh tunnel

Ever since I remember, I have this inability to learn the most basic things, until I actually write down a couple notes or instructions somewhere. This is one of these notes blog posts — so in case it's too basic, just skip over it. Or bear with me.

ssh tunnels — useful and powerful. They can help me with all kinds of trickery — e.g. usually for remoting through a tight firewall setup to access remote resources. So point taken there are a lot of GUIs for this, but if you spend a couple minutes with the ssh man page, you will realize how amazingly simple they are.

My example for an ssh tunnel put to good use is our production gearman setup: The gearmands runs isolated on EC2. On the upside: pretty secure, but the downside is that the service is unavailable when you need to a little live data for some local tests. When we added an interface to get more visibility into the processes we push through gearman, of course we couldn't access it.

A tunnel to the rescue!

Consider this:

[email protected]$ screen -S gearman-ssh-tunnel
[email protected]$ ssh -L 2222: production-gearmand
Linux Ubuntu SMP AMD64

Last login: Sat May  5 16:22:47 2012 from YYY.YYY.YYY.YYY
[email protected]:~$

("ctrl + a + d", to detach from screen.)

So what does that do?

First off, we are starting a session in screen: it's called "gearman-ssh-tunnel". You could use tmux as well, but screen works just as nice.

The consecutive command maps port 2222 on my (local) macbook to a service running on the server production-gearmand (this is via .ssh/config) but only listens on

Your .ssh/config could look like this:

Host production-gearmand
User till
IdentityFile ~/.ssh/gearman.pem

If I wanted to connect to this server in a PHP-script on my macbook, I would use the following configuration:

$client = new GearmanClient;
$client->addServer('', 2222);

Run it from the terminal:

[email protected]$ php gearman-ping.php


Need to stop the tunnel?

The following command lets you resume your session with screen:

[email protected]$ screen -r gearman-ssh-tunnel

Type exit twice, or hit "ctrl + d" to log off the server and "ctrl + d" again to kill the screen. Done.


Bonus points if you use this from your VM in vagrant. But otherwise, that's all for today.