Showing posts with label Zend Framework. Show all posts
Showing posts with label Zend Framework. Show all posts

Sunday, January 31, 2010

Bootstrapping Zend Framework Applications

See Bootstrapping Zend Framework Applications at its new home on bradley-holt.com.

In my previous post I talked about how the Front Controller pattern is implemented in Zend Framework. We saw how every application request can go through the public/index.php script. Everything that your application does is then eventually called from either the bootstrap() or run() method in Zend_Application.

One of the constructor arguments passed to Zend_Application specified the configuration file to use. In the case of the demo blogging application, Postr, you'll see that the configuration file used is application/configs/application.ini. If you look at this configuration file you'll see that there are four sections: production, staging, testing, and development. The staging, testing, and development sections all inherit from production meaning that they will inherit all of its settings, unless overridden (as is the case, for example, with the phpSettings.display_errors setting in testing and development).

The other constructor argument passed to Zend_Application specified the application's environment. For those paying close attention, the environment was actually the first argument and the configuration file was the second argument passed to the constructor of Zend_Application. By default, the demo application is set to run in development mode. This means that the development section from application/configs/application.ini will be used. Remember, development inherits from production so any settings not explicitly overridden from production would be inherited and used.

There's quite a bit that can be setup in the configuration file. However, some things may be easier to (or only possible to) setup programmatically. This is where application/Bootstrap.php comes in. In your Bootstrap class you can write initializers for various parts of your application. These methods should be protected and their names should begin with _init. Let's look at the initializers I've written in the demo application:

  • _initViewHeadTitle() first makes sure that the "view" resource has been bootstrapped and then gets this resource, which we happen to know is an object of type Zend_View_Abstract. We then set the separator used by the HeadTitle view helper to " :: ". This means that each head title appended or prependend will be separated by this string. Next, a title of "Postr" is prepended so that this title will be used on every page.
  • _initPagination() simply sets the partial view script to be used by Zend_Paginator (I plan on further explaining Zend_Paginator in another blog post).
  • _initNavigation() sets up our navigation structure using Zend_Navigation (I plan on further explaining Zend_Navigation in another blog post as well).

In my next post in this series I plan on taking a look at the Model-View-Controller pattern in Zend Framework.

Friday, January 29, 2010

Front Controller Pattern in Zend Framework

See Front Controller Pattern in Zend Framework at its new home on bradley-holt.com.

I recently gave a Zend Framework Introduction presentation at our local PHP Users Group. I built a demo blogging application called Postr that I used as an example throughout the presentation. There was way too much material to cover in the time available so I plan on writing a series of blog posts, each covering a specific area of Zend Framework. Here is the first (and hopefully not the last!) post in this series based on the presentation and demo application.

Like many other frameworks, Zend Framework provides an implementation of the Front Controller pattern. This means that all HTTP requests can be sent through a centralized point. This allows you to take advantage of Zend Framework's routing and Model-View-Controller (MVC) components, if you so choose. By default this is the public/index.php file (click to see the source code). Note that in Zend Framework only the public directory is accessible to website visitors, all of your other directories should be outside of your document root. You'll see several things happening in the public/index.php script:

  1. The APPLICATION_PATH constant is defined. This is the full path to the application directory. You'll see this constant used later.
  2. The APPLICATION_ENV constant is defined. This will typically be either production, staging, testing, or development. This will be used to determine which configuration section to use.
  3. The library directory is added to the include path. This is so that the Zend library code (if you decide to place it in your library directory) or any other libraries used can be found.
  4. A new instance of Zend_Application is created. Two arguments are passed to its constructor: the application environment (defined in 2) and the location of the configuration file. Typically this is application/configs/application.ini. The application path (defined in 1) is used to provide the absolute path to the configuration file.
  5. The application is then bootstrapped and run. It may seem odd to those used to writing PHP scripts, but everything that happens in your application is subsequently called from either the bootstrap() or run() method in Zend_Application. In fact, this is the essence of the Front Controller pattern.

By itself, public/index.php can't make sure that all HTTP requests go through it. If you're using Apache as your web server then you can use its rewrite module to do this (other web servers have equivalent functionality). This is typically done in public/.htaccess. There are several things happening in this file:

  1. First the application environment is set so the application knows if it's running in production, staging, testing, or development mode.
  2. In the demo application, I set the default character set to utf-8.
  3. Some environments require you to set a rewrite base. If needed, this is usually the first part of the URI (e.g. just / if your application is the only thing on the web server or /postr/ if your application is in a subdirectory named "postr").
  4. Turn on the rewrite engine.
  5. Don't rewrite if the requested file is a regular file with size greater than zero, is a symbolic link, or is a directory. This way static files such as images, CSS files, and JavaScript files aren't rewritten.
  6. Otherwise, rewrite the request to index.php.

In my next post in this series I plan on taking a look at what happens during the bootstrapping phase of your Zend Framework application.

Zend Framework Introduction

See Zend Framework Introduction at its new home on bradley-holt.com.

Slides from last night's Zend Framework Introduction at the Burlington, Vermont PHP Users Group are now available online:

The presentation is available under a Creative Commons license.

As I mentioned earlier, there's also a demo blogging application called Postr available on GitHub. The application is available under a free/open source New BSD License so feel free to use, redistribute, and/or modify it however you'd like.

Thursday, January 28, 2010

Learn Zend Framework

See Learn Zend Framework at its new home on bradley-holt.com.

At tonight's (Thursday, January 28, 2010) Burlington, Vermont PHP Users Group meeting I'll be giving a Zend Framework Introduction presentation. I'll be covering how to use several features of Zend Framework and common patterns including:

I've created a demo blogging application called Postr that I'll be using as an example throughout the presentation. Thanks to Jason there is some CSS that makes the application much more usable. I will post the presentation to my SlideShare account after tonight's meeting.

The meeting is from 6:00 PM - 8:00 PM at Office Squared in Burlington, Vermont. If you're in the area and interested in attending then you can register for free on Eventbrite.

Monday, January 11, 2010

Zend Framework Route Context Plugin

See Zend Framework Route Context Plugin at its new home on bradley-holt.com.

I want to share a simple, yet very useful, custom Zend Framework plugin that we use on almost all of our projects. The plugin (and associated code in the layout file) provides the Zend Framework route context as CSS classes on the body element. This allows us to change the design (using CSS) and/or behavior (using unobtrusive JavaScript) on the page based on the Zend Framework route. For example if the module name was default, the controller name was news, and the action was get then the opening of the body element would like this:

<body class="default news get">

There are some limitations. For example, you need to be careful not to overlap module, controller, or action names. If this is a problem for you then you could preface the class names (e.g. module-default, controller-news, action-get).

The RouteContext plugin hooks into the preDispatch event and creates an array of route context strings. This example simply uses the module, controller, and action names as the route context. Often I'll add other contextual strings to this array as needed. This array is then assigned to the view. The layout view script then simply implodes this array into the value of the class attribute using a space character as the glue.

Friday, January 1, 2010

Year In Review

See Year In Review at its new home on bradley-holt.com.

Being the first day of 2010, I thought it would be a good time to take a look back at 2009…

Burlington, VT PHP Users Group

2009 was the second full year of the Burlington, VT PHP Users Group. We had some fun meetings and presentations including:

January
Jason Pelletier gave a presentation on CSS for Developers.
February
Aaron Carlino demonstrated SilverStripe, an open source CMS/framework built in PHP.
March
Special guest Paul Reinheimer gave a presentation called "Easy Problems are the Hard Problems" taking an in-depth look at the easy/hard parts of building web applications.
April
Rob Riggen gave a talk on website performance optimization.
May
Rene Churchill gave a presentation on MySQL database optimization.
July
Matthew Weier O'Phinney gave his Play-Doh: Modelling Your Objects presentation.
August
Matthew Weier O'Phinney presented again in August, this time giving a hands-on unit testing crash course [ODP].
September
September's meeting was a casual get-together instead of a formal meeting and presentation—a change of pace from the typical meeting format.
October
I gave a talk geared towards PHP beginners.
November
November's meeting fell on one of Zend Framework's Bug Hunt Days. Held monthly, Bug Hunt Days are designed to encourage the community to help triage and resolve issues in the framework. Matthew Weier O'Phinney guided us through effective bug reporting and taught us how to contribute patches. As part of Bug Hunt Days, my first Zend Framework patch was accepted, a small addition to the documentation.
December
December marked the second birthday of our local PHP Users Group and that month's meeting turned out to be a fun social event.

Our users group also won a free pass to ZendCon '09, and Jase Roberts was the lucky recipient. He joined fellow Vermonters Matthew Weier O'Phinney, John Valance, and me at the annual PHP conference.

The Browser

Jonathan Butler started a program on our local community radio station called The Browser. It's "a show about the people who bring the world wide web to [Burlington, VT]." Jason and I were on the show twice—once in February and again in August.

Town Meeting Day Vermont, ACM-NE, and Tagnabit

The first Tuesday of March was Town Meeting Day here in Vermont. Citizens throughout Vermont gathered together to elect local officers and vote on budgets. As an experiment we put together a website, tmdvt.net/09, to aggregate content from social media sites around Town Meeting Day Vermont '09. If you used the appropriate tags in your tweets, Flickr uploads, blog posts (if indexed by Technorati), YouTube uploads, and bookmarks on Delicious, then your content showed up on the website. I wrote a post recapping some things we learned from the experiment.

As a result of that project, Bill Simmon and Seth Mobley from Vermont Community Access Media (VCAM) approached us about doing something similar for the Alliance for Community Media Northeast Region (ACM-NE) conference they were organizing here in Burlington, VT. We built acmne.net/09 for the conference and it was a big hit. I spoke on a social media panel (which Liz Schlegel moderated) and helped with a social media workshop at the conference. Colin Rhinesmith, who was on the panel with me and also helped with the workshop, posted a good summary of the conference on his blog.

We then took the idea from Town Meeting Day Vermont and ACM-NE a step further, creating Tagnabit—aggregating tweets, photos, blog posts, videos, and bookmarks for any arbitrary tag. Bill Simmon wrote a good blog post on how Tagnabit could be used.

Jelly/Coworking

I was excited to see Jen Mincar open up a coworking space, Office Squared (o²), here in Burlington, VT in 2009. I think it will help bring more cohesiveness to the local technology community since many of her customers work in technology-related industries. As a precursor to its opening, we hosted a Jelly at Found Line in July, inviting entrepreneurs and freelancers to work in our studio for an afternoon. Here are some photos from the Jelly and another one at the Burlington Free Press.

Vermont Code Camp

September saw the first ever Vermont Code Camp, bringing together people from local technology communities around .NET, PHP, Ruby, and Python. The event was a huge success with 85 attendees and 19 sessions. I had a small part in organizing the event but the real credit goes to Rob Hale, Julie Lerman, and everyone else who organized, volunteered, and presented. I also gave a presentation on Resource-Oriented Web Services as part of the code camp.

ZendCon

ZendCon is the biggest conference of the PHP community, and this year's event was my second ZendCon. What can I say? The talks were excellent. The people were even better. I ended up co-presenting at the UnCon with Michelangelo van Dam and Anna Filina on the role of a PHP user group.

Moving On

2009 seemed to be the year for people in the PHP community to change jobs. Following that trend, I made the move to Found Line full time last month, leaving Vermont Oxford Network. As I said before I'm very happy to have more time to focus on our clients' projects and to work with free/open source software and open standards full time.

Work

2009 was a busy year. Some of the work included:

Phew—a lot to say! I hope you had a good 2009, and have an even better 2010.

Wednesday, December 23, 2009

Common Good Vermont

See Common Good Vermont at its new home on bradley-holt.com.

The other day we launched the first iteration of the Common Good Vermont website. From the about page:

Vermont (pop. 621,000) is a small, tightly knit rural state proud of its independent spirit and high levels of civic engagement. Vermont's independent sector (3000+ organizations, $4 billion annual revenue) plays a primary role in the delivery of human and cultural services and in the preservation of the state's cherished natural resources. Most social services—food, shelter, healthcare and education—are delivered within local and regional community settings.

Often separated by geography (mountains, rivers, lakes), Vermont's 251 towns and 14 counties are increasingly knit together by broadband "build-out". Common Good Vermont leverages these electronic networks to bridge the barriers of Vermont's geography and the "beaten paths" of its hyper-local networks. New human and electronic networking activities will support the delivery of information and innovation to the state's community builders: project volunteers and professionals who, by virtue of their civic and nonprofit roles and responsibilities, are the lifeblood of the "green mountain state". Common Good's place-based and community virtual events are designed to improve the capacity of so many "small networks" that, improve Vermont's unique "quality of life".

Common Good Vermont aggregates content for (and from) Vermont independents and nonprofits by pulling in RSS and Atom feeds including blogs, news sources, social bookmarks, and event calendars. The goal is to serve as an information hub encouraging knowledge sharing and increasing cross-organization communication. Content is currently organized by a combination of taxonomy (categories defined by Common Good Vermont staff) and folksonomy (tags from the feeds themselves). Our goal is to eventually remove the taxonomy layer and have all content organized completely by broad and, to a lesser extent, narrow folksonomy. However, the taxonomy layer is there for now to allow a certain amount of curation while we seek out, connect, and aggregate additional sources of information.

Common Good Vermont is built using Zend Framework and hosted on Rackspace Cloud Sites. Components from Zend Framework used include its MVC system, Zend_Application, Zend_Feed_Reader, Zend_Tag_Cloud, Zend_Search_Lucene, Zend_Paginator, Zend_Db, Zend_Date, Zend_Auth, Zend_Acl, and Zend_Form. Stay tuned for future iterations to the website!

Wednesday, December 2, 2009

RedEye Universal Remote Control

See RedEye Universal Remote Control at its new home on bradley-holt.com.

Today one of our clients, ThinkFlood, launched their RedEye Universal Remote Control for the iPhone and iPod touch. The device and application combination allows you to "use your iPhone or iPod touch to control your TV, stereo, cable box, DVD player, and many other devices that receive standard (infrared) signals." The product launch got some great press coverage including from CrunchGear, Gizmodo, Macworld, iPodNN, Engadget, TUAW, and Wired’s Gadget Lab. Our work with ThinkFlood has included developing their brand identity, packaging, and website.

The latest iteration of the website includes eCommerce functionality allowing ThinkFlood to sell their RedEye device directly to consumers. The eCommerce section includes a shopping cart and an easy-to-use two page checkout process. While the checkout process is simple for end users, there's quite a lot happening behind the scenes with the integration of multiple APIs. The website is built using Zend Framework and thanks to Rackspace Cloud Sites everything has remained running smoothly even with all of the press coverage and associated traffic.

Wednesday, November 18, 2009

Bug Hunting

See Bug Hunting at its new home on bradley-holt.com.

If you are a PHP developer in the Burlington, Vermont area then you should come to tomorrow (11/19) evening's PHP Users Group meeting at the newly opened Office Squared coworking space in downtown Burlington. This month we will be learning how to find and fix bugs in free and open source projects. From the meeting description:

Each third Thursday and Friday of the month, Zend Framework has Bug Hunt Days in which the community helps triage issues and resolve them. These efforts include everything from fixing typos in documentation to creating reproduce cases and capturing them in unit tests to actual creation of patches resolving reported bugs.

Since this month's meeting falls on the third Thursday, Matthew Weier O'Phinney, Project Lead for Zend Framework, thought we could join in on this effort or help contribute to other projects. He will be providing a short presentation on effective bug reporting and triage, after which we will jump into some actual bug hunting on projects you, the attendees, are interested in.

So come with your laptops ready, and let's fix some bugs!

PHP developers of all skill levels are welcome. There are many types of contributions needed to keep free and open source projects moving forward. You will likely have something you can contribute — and you'll learn a lot doing it!

Wednesday, July 29, 2009

Domain-Driven Design

See Domain-Driven Design at its new home on bradley-holt.com.

I am currently reading Eric Evans' Domain-Driven Design book. Having read most of the book I can say that his presentations on Putting the Model to Work and Strategic Design are an amazingly concise overview of the book's content (note that InfoQ provides slides below the videos). If you've been interested in reading the book but just haven't had time yet then I'd recommend watching these two presentations.

I have a lot of experience building web applications that separate business logic from presentation and have been using Zend Framework's model–view–controller (MVC) components for over two years now. This has certainly helped make web applications I work on more maintainable. However, creating effective models (the "M" in "MVC") has always been difficult (this has nothing to do with Zend Framework and has everything to do with the difficulty of modeling in general). The Zend Framework team has been relatively quiet on models since modeling tends to be specific to your application's domain (although Matthew Weier O'Phinney recently gave a great webcast and presentation on modeling in Zend Framework).

The Domain-Driven Design book has helped make a lot of things "click" for me. It drives home the point that modeling is a domain-specific task and that the complexity is usually in the domain, not the technical aspects of your project. If you think the complexity is in the technology then you should question your choice of tools (in my opinion) but in this case perhaps domain-driven design isn't right for you. The book provides many patterns that help keep the focus on the domain. Arguably the most important of these patterns is the Ubiquitous Language which is "a language structured around the domain model and used by all team members to connect all the activities of the team with the software." Other important patterns include Entities, Value Objects, Services, Repositories and Factories.

If effective modeling has been something that you've struggled with then I'd urge you to check out Eric Evans' presentations and then read his Domain-Driven Design book.

Thursday, July 9, 2009

HTML 5, HTTP Methods & REST

See HTML 5, HTTP Methods & REST at its new home on bradley-holt.com.

Lots of very exciting things are happening right now for us web standards aficionados. The big news is the buzz around HTML 5 and its growing support in modern web browsers (modern meaning not Internet Explorer). The current state of web standards makes it difficult, but certainly not impossible, to use the web as a true application platform. HTML 5 promises to change this (maybe not fully until 2022 — but we're patient). Many articles have been written about HTML 5 but there's one tiny, but very important, feature I'd like to focus on here: support for the HTTP PUT and DELETE methods in forms. First, a little bit about REST…

I've talked about REST here before but REST is useful for more than just building web services. REST is an abbreviation for representational state transfer and is an architectural style for building software. The web itself is built using REST so it is a proven and scalable architecture. Unfortunately many web developers ignore REST to their detriment. Conforming to REST principles can help with search engine optimization (SEO) as well as make your web applications more usable (through predictability of actions) and scalable (the web itself has scaled to massive proportions).

Using a RESTful approach, every URL is a representation of a resource (a noun). These resources can then be retrieved and manipulated (have their state changed) using a standard set of verbs. These verbs are actually HTTP methods. There are a whole bunch of verbs/HTTP methods but only worry about four of them (at least for now): GET, POST, PUT, and DELETE. Here is an example of how some nouns and verbs can be used to together, borrowing from the Atom Publishing Protocol (APP):

HTTP methodURIresult
GET
/people
GETs a collection of people
POST
/people
POSTs a new person to the collection (using data in the POST request)
GET
/people/bradley-holt
GETs bradley-holt
PUT
/people/bradley-holt
PUTs an updated version of bradley-holt (using data in the PUT request)
DELETE
/people/bradley-holt
DELETEs bradley-holt

The problem was that up until now there was no way to specify a form method other than GET or POST. This meant that everything had to be tunneled through POST (or had to be done using JavaScript) which, while not technically incorrect, was incovenient and did not allow web developers to fully express the intent of user actions. HTML 5 specifies that forms can now have the methods of PUT and DELETE as well. This simple addition is one small way in which HTML 5 will allow the web to become more of a fully-feature application platform.

For you Zend Framework developers: I just learned today that Zend Framework 1.9 will include a new REST router which will help web developers adhere to RESTful principles. Please use it and also use the new PUT and DELETE methods in HTML 5 forms as browser support catches on.

Monday, June 15, 2009

Tagnabit Usage

See Tagnabit Usage at its new home on bradley-holt.com.

It's been two weeks since we launched tagnabit. I want to share some information about how people have been using tagnabit. Some of the most popular tags used so far include:

btv
BTV is the airport code for Burlington, Vermont (where we are located). This tag is pretty heavily used on Twitter to represent our city, but it seems to have other meanings on the other social media sites.
btvsmb
A local event, the Burlington Social Media Breakfast took place a few weeks ago.
acmedia09
Next month in Portland, Oregon is the Alliance for Community Media's International Conference and Exhibition. The activity so far has all been on Twitter. If it's anything like acmne09 then I won't be surprised to see lots of photos, blog posts, videos, and bookmarks once the conference gets started.
tek09
php|tek 2009 was a PHP Conference that took place last month in Chicago, Illinois. While tagnabit actually launched after the conference was finished, it was an example tag that I used to explain the idea behind tagnabit to several people in the PHP community. There's lots of great content tagged with tek09. Tagnabit is built using PHP and Zend Framework in case you're wondering what the connection is.
cxage
Leadership in a Connected Age conference - also a local event.
champ400
The tag for the Celebrate Champlain Quadricentennial events taking place here this summer (sensing a local trend?). There will be lots of happenings so hopefully there is a good amount of participation in tagging content around the events. Vermont Public Radio is encourage people to tag content about Champlain 400 as well, so that should help.

On a more serious note, another tag worth mentioning (although I don't think anyone's used tagnabit for this yet) is the iranelection tag. There is a constant stream of tweets, photos, blog posts, videos, and bookmarks using this tag. Our thoughts are with the Iranian people.

Tell us how you've been using tagnabit. Do you plan on using it for an upcoming event? Are you mainly using it to follow tags or are you also posting content? We've got lots of ideas for improving tagnabit but would love to hear your thoughts! You can either comment here or use the tagnabit tag to give us feedback through Twitter, Flickr, Technorati, YouTube or Delicious.

Monday, June 1, 2009

Tagnabit Launched!

See Tagnabit Launched! at its new home on bradley-holt.com.

Last night we announced the launch of tagnabit, a social media aggregator. It's "a service that aggregates tags from popular social media websites. It is useful for conferences or other events. Participants can use a shared tag across Twitter, Flickr, Technorati, YouTube and Delicious. Tagnabit then aggregates this content in one place." The idea originally started with Town Meeting Day Vermont and then was used for the Alliance for Community Media Northeast regional conference. People found it useful, so we decided to make a "generic" version that basically has the same functionality as these sites, but for any arbitrary tag. Bill Simmon has a few ideas on how tagnabit can be used.

The functionality behind tagnabit was built using Zend Framework (MVC components, Zend_Feed, Zend_Service_Flickr, and Zend_Cache). The client side is all semantic XHTML (with a few Microformats), CSS, and a few JavaScript enhancements (using jQuery). We've got plans for some new features - but we're curious to see how people use the site first. If you've got feedback, please send it our way via Twitter, Flickr, Technorati, YouTube or Delicious by tagging your content with tagnabit (#tagnabit on Twitter).

Friday, October 24, 2008

PHP In Google App Engine?

See PHP In Google App Engine? at its new home on bradley-holt.com.

According to the newly posted App Engine Product Roadmap, there are plans to add "support for a new runtime language." In an email to the Google Apps Small Business Solution Providers mailing list Google had this to say:

"Of particular interest, may be payment for additional resource usage and a new runtime language - I can't say what this language is, but you can probably guess if you've been following along with community demand."

Looking at the issue list, support for Java is the most requested item followed by support for PHP, Ruby, then Perl. If you haven't already, please go star the "support for PHP" issue (please don't comment on it as it will email everyone who has already starred it - just star it!). Of course, I'm hoping Zend Framework is the framework of choice for all the App Engine specific APIs as well.

Thursday, October 23, 2008

Zend_Container Thoughts

See Zend_Container Thoughts at its new home on bradley-holt.com.

It seems that there's some interest in my Zend_Container proposal including possibly using it as part of Zend_Application. I still need to move Zend_Container from "New" to "Ready for Review" but first I need to add some more details to the proposal. I want to talk about some thoughts on Zend_Container that may be helpful in understanding how it could be useful. For those who aren't familiar with it, Zend_Container is a proposal for a simple dependency injection container in Zend Framework.

I have been asked to show some more use cases for Zend_Container. I think the main thing that people want to see (correct me if I'm wrong) is how Zend_Container would be used as part of a larger web application. In order for Zend_Container to work, it needs to "contain" all of the components that it will be responsible for managing. This means that every component that will either a) be a dependency for other components or b) have a dependency on other components (or both) needs to get added to the container.

In the proposal I show an example of the getComponent method as a way to get instances out of the container. However, use of this method is discouraged. You should instead use setter injection (I'm not sure yet if the proposal will support constructor injection) and let the container provide the instance for you. Dependency injection is sometimes referred to as "inversion of control (IoC)" because it requires you to invert your thinking. In your individual components you are giving control over to the container and letting it provide your dependencies for you rather than reaching out and fulfilling these dependencies yourself (as is done currently with Zend_Registry). This is why every component needs to be added to the container — how else would the container know what to inject or even be able to perform this injection?

This inevitably leads to the question, how do we bootstrap all of this? In other words, how do we get all of these components into the container in the first place so all of this "magic" can happen? In the proposal, I showed examples of manually adding components using the addComponent method. This is a great way to add components and there is nothing wrong with doing this. However, this could start to become impractical if you have a lot of components to add to the container. Another option is to use configuration to add all of the components. I don't have an example of this yet in the proposal, but the basic idea is to list a bunch of components in your configuration and let Zend_Container add all of the components based on this information. This is more practical when you have a lot of components to add to the container.

Another option, which is not yet in the proposal, is to use a combination of directory/file scanning and reflection to add components. This could be hugely beneficial to modular applications - simply drop in your module directory and Zend_Container could automatically load components from your module. This is the sort of thing that I think the people working on Zend_Application thought might be helpful (let me know if I'm way off-base here). Of course, this opens up a host of potential efficiency issues that would need to be thought through (i.e. components should probably be "lazily" loaded and implementation/interface mappings maybe should be cached).

While I haven't yet provided any more use cases, I hope this information is helpful in understanding the role Zend_Container could play within Zend Framework. As always, I'm open to feedback even though the proposal isn't officially "Ready for Review." So far I've mainly focused on the "pure" dependency injection parts of the proposal so any other ideas on how Zend_Container could be used as part of a larger application would be great.

Wednesday, October 22, 2008

BTV PHP UG Meeting

See BTV PHP UG Meeting at its new home on bradley-holt.com.

The Burlington, VT PHP Users Group will be meeting tomorrow night at Bluehouse Group in Richmond. David Walsh of Standards Technology Group (STG) will be giving a demo of STG's web application. STG will also be providing massive amounts of pizza. Matthew Weier O'Phinney, Software Architect for Zend Framework, will be giving a presentation on using Dojo, a JavaScript framework, within Zend Framework. More details are available here.

Monday, October 20, 2008

Found Line Software License

See Found Line Software License at its new home on bradley-holt.com.

We recently made the strategic decision to license all software developed by Found Line under the New BSD License. This is a free/open source software license meaning that our clients will have the four freedoms as outlined by the Free Software Foundation. Basically, this means that clients are free "to run, copy, distribute, study, change and improve the software" that we develop for them. The New BSD License also gives our clients another, more controversial, "freedom": the "freedom" to turn the free/open source software we have licensed to them into proprietary, non-free/non-open source software. This is a "freedom" we hope is not exercised but is something we understand may be important to our clients.

We made this decision for several reasons. We are strong believers in the free/open source software movement. To us, this means not just using free/open source software but also contributing to free/open source software. While this software is currently only licensed to individual clients, we plan on licensing specific components publicly in the future (and, of course, individual clients currently have the right to do this as well). For now, this decision makes it really easy for us to publicly release specific components to the community as it makes sense.

Many of our web applications are built using existing libraries, Zend Framework being the most common. Zend Framework is also licensed under the New BSD License so this provides consistent licensing for our clients. Also, I would like our business to contribute back to Zend Framework and this license parity helps make this simpler.

This licensing allows us to give our clients the most freedom while still protecting our right to reuse individual components (which helps keep costs down). We are in the business of creating value for our clients and are not interested in locking them into proprietary software contracts. This licensing gives our clients many options such as switching to another vendor in the future or even bringing web development work in-house. If clients are going to pay us to develop, maintain, or extend their web applications we want this to be because we're the best team for the job — not because they don't have a choice due to vendor lock-in.

Tuesday, October 7, 2008

ZendCon Summary

See ZendCon Summary at its new home on bradley-holt.com.

Rafael Dohms has posted a good summary of ZendCon '08. He touches on several topics including performance, testing and code analysis, PHP's integration with other technologies, Zend Framework, and some interesting things to look forward to in 2009 including Ibuildings' PHP Center of Expertise.

Saturday, September 27, 2008

Testing Requirements with Unit Tests

See Testing Requirements with Unit Tests at its new home on bradley-holt.com.

I'm currently working on a project where the client is running their own web server that I will not have direct access to. This is actually a good thing in that it is a nice way to enforce the separation of the development and integration environments from the staging and production environments. However, how do I be sure that all of the system requirements will be met so that I can address any potential problems early on in the project? Sure, I could just give them a file with phpinfo() in it and have them send me the results. However, I plan on also shipping them unit tests for the application so why not have the requirements tested through unit tests as well?

My first thought was, since the application is being built in Zend Framework, just ship them the Zend Framework unit tests. It turns out there are a lot of unit tests and they have some heavy memory requirements. So, I decided on a simpler approach. I would run unit tests that simply tested for the requirements outlined in the Zend Framework documentation. Here are the tests:

/**
* The Requirements test case.
*
* @category Requirements
* @package Requirements
* @copyright Copyright (c) 2005-2008 Found Line, Inc. (http://www.foundline.com/)
* @license http://www.foundline.com/legal/software-license/ New BSD License
*/
class Requirements extends PHPUnit_Framework_TestCase
{

public function testVersionOfPhpIs5Dot1Dot4OrLater()
{
$this->assertTrue(version_compare(PHP_VERSION, '5.1.4', '>='));
}

public function testVersionOfPhpIs5Dot2Dot3OrLater()
{
$this->assertTrue(version_compare(PHP_VERSION, '5.2.3', '>='));
}

/**
* @dataProvider requiredExtensions
* @param string $extensionName the name of the extension for which to test
*/
public function testExtensionLoaded($extensionName)
{
$this->assertTrue(extension_loaded($extensionName));
}

public static function requiredExtensions()
{
return array(
'apc' => array('apc'),
'bcmath' => array('bcmath'),
'bitset' => array('bitset'),
'ctype' => array('ctype'),
'curl' => array('curl'),
'dom' => array('dom'),
'gd' => array('gd'),
'hash' => array('hash'),
'ibm_db2' => array('ibm_db2'),
'iconv' => array('iconv'),
'interbase' => array('interbase'),
'json' => array('json'),
'libxml' => array('libxml'),
'mbstring' => array('mbstring'),
'memcache' => array('memcache'),
'mime_magic' => array('mime_magic'),
'mysqli' => array('mysqli'),
'oci8' => array('oci8'),
'pcre' => array('pcre'),
'pdo' => array('pdo'),
'pdo_mssql' => array('pdo_mssql'),
'pdo_mysql' => array('pdo_mysql'),
'pdo_oci' => array('pdo_oci'),
'pdo_pgsql' => array('pdo_pgsql'),
'pdo_sqlite' => array('pdo_sqlite'),
'posix' => array('posix'),
'reflection' => array('Reflection'),
'session' => array('session'),
'simpleXml' => array('SimpleXML'),
'soap' => array('soap'),
'spl' => array('SPL'),
'sqlite' => array('SQLite'),
'standard' => array('standard'),
'xml' => array('xml'),
'zlib' => array('zlib'),
);
}

}

Note that I've checked for both the recommended PHP version 5.2.3 and the required PHP version 5.1.4. Also, I've tested for both hard and soft dependencies for all components. This means that many of these tests could fail and my application could still be OK. I wanted as much information as possible so that I can detect any potential problems before I write too much code. As the specific requirements for this application become clearer, I will update the test to add or remove requirements. Of course, once there is real code and unit tests these requirements tests will become irrelevant. The point is to test for the presence of these requirements before I write the code.

Running these tests with the command phpunit --testdox Requirements.php (I've actually wrapped this into a bigger test suite, but that's outside the scope of this blog post) gives me the following output on one of my development machines:

PHPUnit 3.3.1 by Sebastian Bergmann.

Requirements
[x] Version of php is 5 dot 1 dot 4 or later
[x] Version of php is 5 dot 2 dot 3 or later
[x] Extension loaded with data set "apc"
[x] Extension loaded with data set "bcmath"
[x] Extension loaded with data set "bitset"
[x] Extension loaded with data set "ctype"
[x] Extension loaded with data set "curl"
[x] Extension loaded with data set "dom"
[x] Extension loaded with data set "gd"
[x] Extension loaded with data set "hash"
[ ] Extension loaded with data set "ibm_db 2"
[x] Extension loaded with data set "iconv"
[x] Extension loaded with data set "interbase"
[x] Extension loaded with data set "json"
[x] Extension loaded with data set "libxml"
[x] Extension loaded with data set "mbstring"
[x] Extension loaded with data set "memcache"
[x] Extension loaded with data set "mime_magic"
[x] Extension loaded with data set "mysqli"
[ ] Extension loaded with data set "oci 8"
[x] Extension loaded with data set "pcre"
[x] Extension loaded with data set "pdo"
[ ] Extension loaded with data set "pdo_mssql"
[x] Extension loaded with data set "pdo_mysql"
[ ] Extension loaded with data set "pdo_oci"
[ ] Extension loaded with data set "pdo_pgsql"
[x] Extension loaded with data set "pdo_sqlite"
[x] Extension loaded with data set "posix"
[x] Extension loaded with data set "reflection"
[x] Extension loaded with data set "session"
[x] Extension loaded with data set "simple xml"
[x] Extension loaded with data set "soap"
[x] Extension loaded with data set "spl"
[x] Extension loaded with data set "sqlite"
[x] Extension loaded with data set "standard"
[x] Extension loaded with data set "xml"
[x] Extension loaded with data set "zlib"


There are a couple of potential problems to be aware of. First, PHPUnit will have to be installed on the machine that this will be tested on. This should probably only be done on the staging machine, not the production machine. Second, the CLI version of PHP often uses a different php.ini file then the CGI or ISAPI version. This means that some requirements may actually be available to your web application but they will fail the test when run at the command line.

Monday, September 22, 2008

ZendCon 2008

See ZendCon 2008 at its new home on bradley-holt.com.

ZendCon 2008 wrapped up last week. This was my first time going to ZendCon and it was definitely worth it. There were over 650 people and over 60 sessions at the Santa Clara conference. I'll try to post summaries and highlights from the sessions I attended. It was a great opportunity to attended presentations from some of the most well respected people in the PHP community including Vermont's own Matthew Weier O'Phinney (Zend Technologies), Mike Naberezny (Maintainable Software), Sebastian Bergmann (eZ Systems), Derick Rethans (eZ Systems), Ben Galbraith (Ajaxian.com) , Marcus Boerger (Google), and Ben Ramsey (Schematic).

Zend Certified Engineer (ZCE) in Zend FrameworkLast Tuesday during the opening keynote Zend announced the new Zend Framework certification. I was fortunate enough to get a testing slot on Thursday morning. After reading the 214 page study guide on Wednesday I passed the test, so am now a Zend Certified Engineer (ZCE) in Zend Framework! If you plan on taking the test, I definitely recommend reading the study guide. I've been using Zend Framework since 1.0 and I'm not sure I would have passed if I hadn't read the study guide.