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

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!

Example

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.

Install

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

$ pear channel-discover easybib.github.com/pear
...
$ pear install easybib/Easybib_Form_Decorator
...

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

Setup

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://github.com/lagged/Zf_Crud.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"
  }
}

Code

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.

<?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';
CrudAutoload::register();

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

Next, create a plain model using Zend_Db_Table_Abstract:

<?php
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:

screenshot-zf_crud

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():

<?php
// 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

Fin

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!

The demand web

I read a blog entry this morning entitled "The unbearable lameness of web 2.0" (scroll down for the English version).

In his blog entry Kris Köhntopp states how he's not satisfied with the status quo, and of course that he said it all before — in a nutshell, he wants a social networking standard which is adhered to across all platforms, e.g. Twitter, Facebook and whatever else there is in between.

This standard includes things like:

  • a better like/friend/subscribe model
  • auto-classification of contacts into interest groups (basically diaspora's aspect feature in automatic)
  • aggregating and analysis of shared items in your own stream and the stream of your friends/followers
  • providing sources (e.g. to be able to find the origin of a shared item vs. seeing it shared 20 times in your stream)
  • … and language detection (and possibly translation)

I hope I got it all right (in a nutshell, of course).

Fundamental problems

The blog entry itself and the comments on his blog entry suggest how trivial and easy these features are, so I'm wondering why exactly no one implemented those yet?

Well, let me try to answer that.

Trivial?

These problems are not trivial and actually require a little more thought ("Googledenk", as Kris put it). I know there are services already that implement some of these features, but who knows apparently it's not that easy after all — but feel free to prove me wrong.

The average user

These problems are also not average user problems.

Yeah, there might be 10,000 or maybe even a 100,000 people on Facebook who have these problems, but not 50,000,000. Facebook being slightly more business oriented than the average "go build it for me" social media blogger, will build a feature for 50,000,000 first before it caters to the problems of those maybe 100,000 power users.

Power users are not their target audience. Mom and dad type of people are.

Given that there are indeed services that implement these features (or at least some of them) and their general lack of traction, kind of supports my argument as well. Apparently, this is something not too many people need.

A Standard!

Does anyone remember how well OpenSocial worked out? Good luck with that.

Can someone, please?

To all those people are pissed at diaspora because it's not what they thought it would be like.

Get a grip and contribute for f's sake.

If you want something to happen, maybe you just have to go further than to your blog to bitch about it. It's really easy to rant on Twitter or your blog (see this post for example :-)), but GTD — that's the hard part.

Playground

Last but not least people forget that when they get into social networking they have no rights.

Of course in some countries you may have a right to your data, but that's basically it.

There is no given right to access a platform, no right to certain features or how they are designed and there sure as hell is no right to any kind of API. Facebook, Twitter and StudiVZ — they all allow users to come play. There's nothing for a user to demand.

Fin

My point of view. If you beg to differ, go build it.

Just add blame

I swore myself to only post meaningful stuff to this blog, so basically, no rants, ever. But!

The discussion revolving around Twitter and Rails (versus Scala) did remind me of something: If you've doing PHP for a while and know people who are programming not in PHP, you probably heard it all before. PHP guys (and girls) are being look down on and mocked by people of other programming and scripting languages. And that is despite ...

  1. ... the overall acceptance and distribution of the language
  2. ... the millions of free lines of code in open source projects and other code repositories
  3. ... the countless great examples of PHP in the enterprise
  4. and the amazingly short time to market when you develop with PHP

Those are a few good things to say about this fine language called PHP. Unfortunately they are never taken into consideration when you bash people who use it.

Instead you tell them about the short comings of several pieces of software such as phpBB, Mambo/Joomla and Wordpress who have had a lot of issues in the past but never the less are more popular than virtually any of their open source counterparts in the other languages.

Now, because a lot of Ruby people have a strong dis-like for PHP, you may think they deserve this. I don't think they, or Ruby, do.

I am perplexed how Alex Payne handles the current Scala/Ruby shoot out over at Twitter.

  • I'm amazed that someone with his experience and knowledge oversees the obvious short comings of several people who worked on the Twitter code base over the past years.

  • I'm amazed that he oversees all the crap they implemented.

  • I'm amazed that he oversees how they were and still are suffering from the most classic NIH.

And all to blame it on the language — Ruby.

Anyway, there may be plenty to argue about Ruby (or maybe just Rails). But blaming the language because of the inability of a developer (or multiple) is not the way to do it. It just makes you look very ignorant.

I sure hope Scala lives up to Alex' expectations, but if it doesn't — just blame it on Scala!