Posts tagged 'zf'

Using the new autoloaders from Zend Framework 1.12

published on June 22, 2012.

The latest, and last, release of the Zend Framework 1.x series is just around the corner as ZF 1.12.0RC1 was announced this week. As I still have projects running ZF1 I thought about giving the most interesting new feature (for me) a spin - the new autoloaders which are backported from ZF2.

Note: the code below was updated to work with ZF 1.12.0RC2. Should still work with RC1, too.

I decided using the classmap autoloader as the main autoloader, and the good ol’ standard autoloader as the fallback autoloader. For the classmap autoloader to work we need to create a classmap. ZF1.12 comes with a tool, located in the bin directory, called classmap_generator.php, which will generate the classmap for us:

$ cd /path/to/project/library
$ php /path/to/zf1.12/bin/classmap_generator.php 

This will generate a PHP file called autoload_classmap.php in the library directory and it will have classname - filename mappings of the classes/files from that directory.

Next, need to change the index.php a bit to tell ZF to use the new autoloaders:

<?php
// normal setting up of APPLICATION_PATH and other constants here ...
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
require_once '../library/Zend/Loader/AutoloaderFactory.php';
// As of ZF1.12.0RC2 the Zend prefix is not autoregistered
// with the standard autoloader, so we need to require explicitly
// the ClassMapAutoloader.php
require_once '../library/Zend/Loader/ClassMapAutoloader.php';
Zend_Loader_AutoloaderFactory::factory(
    array(
        'Zend_Loader_ClassMapAutoloader' => array(
            __DIR__ . '/../library/autoload_classmap.php',
            __DIR__ . '/../application/autoload_classmap.php'
        ),
        'Zend_Loader_StandardAutoloader' => array(
            'prefixes' => array(
                'Zend' => __DIR__ . '/../library/Zend'
            ),
            'fallback_autoloader' => true
        )
    )
);
// set up Zend_Application as normal here ...

and that’s about it - the autoloader will load classes from the classmaps, but if it fails to do so, it will fall back to the standard autoloader.

Stripping out require_once calls

The Zend Framework manual has a section on how to improve performance of the framework itself, and one of the suggestion is to strip out the require_once calls from the library. I had to alter that find/sed command combination a bit in order to make it work with the classmaps:

$ find . -name '*.php' \
  -not -wholename '*/Application.php' \
  -not -wholename '*/Loader*' \
  -print0 | xargs -0 \
  sed --regexp-extended \
  --in-place 's/(require_once)/\/\/ \1/g'

If I’m not wrong in reading my “debugging” echo statements, the standard autoloader gets called only once - to load the classmap autoloader itself - everything else is loaded via the classmaps. Pretty cool.

Happy hackin’!

Zend Framework full page cache tips

published on February 11, 2012.

When I started rewriting this blog, I knew from start that I want to use Zend Framework’s full page caching,
as, I think, that’s the best cache for this purpose. Not much going on
on the front end, much more reads than writes, no ajax or any other
"dynamic" content. While implementing the cache, I ran into two issues.

The
first problem was that the cache files were created, but they were
never valid - on each request a new cache file was created. It was a
noob(ish) mistake - I had two calls to Zend_Session::startSession() in
my code, which made the session ID always to change which made the cache
validity test to fail. Removed the second call and all was well. Or so I
thought…

I moved the code to staging to run some final tests
before pushing it live, but the cache started failing again. This time
the cache files weren’t even being created! The same code works on my
machine, fails on staging. The only difference was that I had turned off
the loading of Google Analytics in the development environment. But…
that can’t be it, right? Wrong. On every request the values of the GA
cookies are different. The full page cache has a set of settings which
dictates what variables are taken into account when creating an ID for
the cache: make_id_with_xxx_varialbes where "xxx" is one of get, post, files, session, cookie and by default all are set to true. Setting make_id_with_cookie_variables to false made the cache to disregard the always changing GA cookies which made the cache start working again.

So,
if Zend Framework’s full page cache starts failing for you, check the
contents and behaviours of all the variables - get, post, files,
session, cookie - and play around with the cache settings until it
starts working again.

Happy hackin’!

Contributing to Zend Framework 2

published on November 10, 2011.

Today a pretty big news hit the interwebs: as of today, the CLA is not required any more to contribute to Zend Framework 2! This means anyone can issue pull requests and submit patches to the new version. Note that if you want to contribute to Zend Framework 1, you still need a signed CLA. I’ve decided to write a quick post with additional information and links, to make it easier getting started with the contributions!

Back in July I wrote a post on helping out with Zend Framework 2, so consider this post as a second part of that post ;)

The development is on git. The original repo is http://git.zendframework.com/?a=summary&p=zf, while the one on Github is a mirror which gets updated twice a day. Not that it matters much, as everyone forks the Github version and sends pull requests against that.

The issues are kept on a Jira instance: http://framework.zend.com/issues/browse/ZF2. Please make sure you are actually on the Zend Framework 2 project, as we have a separate project for ZF 1. Create an account on Jira and off you go. If I’m not mistaken, it is connected to the ZF wiki, so you can use that too.

All ZF2 related stuff on the wiki is located in it’s own section. It’s full of goodies, so take your time to browse it.

We hold biweekly IRC meetings: every second Wednesday, 17:00 UTC. The next one is going to be on November 23rd. Prior to each meeting we set up an agenda, vote on it, decide who will be moderator and then just discuss whatever is there to discuss. The meetings are held on the #zf2-meeting channel, on Freenode. All agendas and logs from previous meetings can also be found on the wiki.

We have a separate #zftalk.2 IRC channel devoted to discussing all things ZF2!

Subscribe to the mailing lists; you’ll be especially interested in the “Contributors” section; all big and small things are discussed there.

A new “thing” introduced to the ZF ecosystem are the RFCs. We’re using those when a new architecture is discussed or a rewrite/refactor of an existing component is to be done.

New components need to go through a proposal process. The proposal process is rumoured to get an overhaul, but (hopefully!) it won’t be going away.

There is also a blog set up, so be sure to subscribe to the feed.

Great and exciting times are ahead of us and I welcome all new ZF contributors! :)

Happy hackin’!

A Zend Framework 2 EventManager use case

published on October 19, 2011.

With Zend Framework 2 beta 1 released yesterday and some free time to spare, I decided to finally try and tackle one of the “scariest” additions to the Zend Framework - the EventManager component. Now, I won’t go into details about this whole event voodoo, Matthew already did that. Twice.

Basically, this allows us to have one piece of code to trigger an event and to have one or more listeners listening to this event. When the event gets triggered, the listeners are called and then we can do something, like caching or logging. Logging or caching. Caching. Logging…

See, that’s my problem. All the event examples stop at logging and caching. Truly there must be some other example for which this event stuff can be used for. (Yes, I know. The whole dispatch process is now event driven or whatnot in ZF2, but I need event examples in my application, not in the framework.) I don’t claim I found a perfect example for the events, but I tried.

The problem

One of the most “repetitive” places in my code I found is the save method in my models. Pass an array of data to it, possibly do something with that data, validate it, persist it, maybe do some more data mangling, return true/false to the caller. Over and over again, but just with enough difference between different models that there is actually no double code to pull out to an abstract class or some such.

Say, for example, we have a Post of some sort. It has a title and a slug created from the title. Standard stuff, nothing fancy. For the Post to be valid, it needs to have both the title and the slug set.

Now, without the EventManager, the save method could have a similar flow:

  • call the save method, passing in the data array
  • check if the data array has a slug set, if not, create one from the title
  • validate the data array, to make sure both title and slug are properly set
  • save the post

As I said, pretty standard stuff, so I’ll assume you can imagine that piece of code in your head (read, I’m lazy to write it). The problem: the save method is stuffed with data preparing and validation code.

Using the EventManager

This is where, I hope, the EventManager can help. Call the save method and, just before the persist call, trigger a “pre-save” event and then persist the data. Attach two listeners to this “pre-save” event; the first will do the data preparation, the second will do the validation. There, done. Now the save method doesn’t have that unneeded code around it and can be pulled out to an abstract class, all that is in the event listeners.

Let’s see some code:

<?php

// This is the Post object

class Post
{
    protected $events = null;

    public function events()
    {
        if ($this->events === null) {
            $this->events = new Zend\EventManager\EventManager(__CLASS__);

            $this->events->attach('save', array('SlugifyPost', 'slugify'), 100);
            $this->events->attach('save', array('ValidatePost', 'validate'), 90);
        }

        return $this->events;
    }

    // this method can be pulled out to an abstract model class
    // and reuse it for all the models that extend it
    public function save($data)
    {
        $this->events()->prepareArgs($data);
        $response = $this->events()->trigger('save', $this, $data);

        echo 'data saved! ' . json_encode($response->last());
    }
}

I just set a “save” event to be triggered and attached two listeners to that event, the slugify and the validate methods. When the save method gets called, the event is triggered and the EventManager calls our listeners. One fairly important point here is the prepareArgs method call, which prepares the event arguments in such way, that when these arguments (the $data array in this case) are modified in one listener, this modification is reflected for the other listeners, too. If you don’t want to modify the arguments in the listeners, this call can be omitted. As for the rest of the code, it’s explained in Matthew’s posts and in the ZF2 docs.

And here’s how the slugify method modifies the data:

<?php

class SlugifyPost
{
    public function slugify($event)
    {
        $data = $event->getParams();

        $event->setParam('slug', strtolower(str_replace(' ', '-', $data['title'])));

        return $data;
    }
}

Calling the save method itself remains as it was before introducing the EventManager, which means I could add this to my models without changing the API and not break anything! Genius! Theoretically, anyway…

<?php

$post = new Post;

$values = array(
    'title' => 'My post'
);

try {
    $post->save($values);
} catch(\InvalidArgumentException $e) {
    echo $e->getMessage();
}

You can find this complete example on Github.

Thoughts?

So, what do you think? Does this approach makes sense to you? Do tell. I kinda like the idea, but time will tell in the end, as always.

Happy hackin’!

Helping out with Zend Framework 2

published on July 27, 2011.

OK, here are some tips and resources so you can start helping out and contributing to Zend Framework 2.0 :)

First, here’s a nice wiki page with some links on how to start with Zend Framework 2. Be sure to check out the Zend Framework 2.0 patterns tutorial slides and the webinar on the same topic (you need to log in to watch it, but the registration is free, so no excuses).

The development is happening on github, so that’s a nice starting point to get your hands dirty with some code. On the wiki there’s a Zend Framework Git Guide to get you started. Pay close attention to the “Working on Zend Framework” chapter.

As Matthew noted in this thread you can:

Fix unit tests!

Once you forked and cloned the github repo, cd to the zf2/tests directory and simply make the tests there pass! Of course, there are a lot of tests there, so you might want to start with something easy and small; for example I picked the Zend\Dojo component :P

Anyway, once you’re in the tests directory, just type:

robert@odin:~/www/zf2/tests$ phpunit --verbose Zend/Dojo

or:

robert@odin:~/www/zf2/tests$ phpunit --verbose Zend/Dojo/DojoTest.php

and watch the tests pass or fail. If they pass, good, if they fail, try to fix them and make them pass! I tell you, it’s fun! By using the “–verbose” flag you’ll get more (helpful) info about the tests.

Port Zend\Service

I haven’t look into it yet, so just quoting from the mailing list:

  • Port Zend\Service classes that interest you to namespaces, new

    exception usage, etc.

but I believe if you start from the tests for the services too, you should be all set!

Port ZF1 patches to ZF2!

Even if ZF2 is under development, ZF1 is still taken care of: that means, a lot of patches are present in ZF1 which are not in ZF2 (cause they were added after ZF2 branched off of ZF1, obviously…). Some patches will probably not be needed thanks to the rewrite, but some patches will be! So head over to the issue tracker, search for recently (where recently is, say… this year?) resolved and fixed issues, see if they have a patch attached, if yes, open the patch, see if that patch is already in ZF2, if not, add it, issue a pull request, move on to the next issue.

Play with the existing code!

The official Zend Framework Quickstart is also on github, with different features on different branches! Fork it, clone it, test it, make it, break it, fix it… I myself am rewriting a ZF1 based application to ZF2, so you can have a look at that too!

I have also created a few gists about using the new helper loaders/brokers/plugins.

That’s it for now, if I remember/find anything else, I’ll update the post. Of course, if you have to add something, fire away! :)

Happy hackin’! :)

Robert Basic

Robert Basic

Software developer making web applications better.

Let's work together!

I would like to help you make your web application better.

Robert Basic © 2008 — 2020
Get the feed