Zend Framework 1.11.0 FINAL Released

The Zend Framework team is pleased to announce the immediate availability of the general access release of Zend Framework 1.11.0.

This release is the culmination of several months of effort by contributors and Zend Framework partners, and offers several key new features, including support for mobile devices and the first stable release of the SimpleCloud API.

You may download the release from the following location:

http://framework.zend.com/download/latest

The following is a summary of new features and capabilities introduced in version 1.11.0

mobile support

Zend Framework 1.11 marks the first release with explicit support for mobile devices, via the new component Zend_Http_UserAgent. This component was developed by Raphael Carles. Carles is CTO of Interakting, the digital agency of Business & Decision Group of France. Interakting employs 150 PHP professionals to build industrial PHP projects, and its clients include Canal +/Vivendi, BNP Paribas, Samsung France, Ministry of Education, Alapage (Orange), Orange Tunisia, and many others. As such, they have extensive experience in supporting mobile devices, and stepped forward to contribute to Zend Framework, which they leverage in their projects.

Zend_Http_UserAgent performs two responsibilities:

– User-Agent detection

– Device capabilities detection, based on User-Agent

The component includes a “features” adapter mechanism that allows developers to tie into different backends for the purpose of discovering device capabilities. Currently, Zend Framework ships with adapters for the WURFL (Wireless Universal Resource File) API, Tera-WURFL, and DeviceAtlas, with more planned for the future.

Luca Passani, author and lead of the WURFL project, has provided an exemption to Zend Framework to provide a non-GPL adapter accessing the WURFL PHP API.

Additional hooks into the component are provided via a Zend_Application resource plugin, and a Zend_View helper, allowing developers the ability to return output customized for the detected device (e.g., alternate layouts, alternate images, Flash versus HTML5 support, etc.).

Zend_Cloud: SimpleCloud API

During ZendCon 2009, Zend announced a prototype of the SimpleCloud API.

This API was to provide hooks into cloud-based document storage, queue services, and file storage.

Zend Framework 1.11.0 markes the first official, stable release of Zend_Cloud, Zend Framework’s PHP version of the SimpleCloud API. Current support includes:

– Document Services:

– Amazon SimpleDB

– Windows Azure’s Table Storage

– Queue Services:

– Amazon Simple Queue Service (SQS)

– Windows Azure’s Queue Service

– All adapters supported by Zend_Queue:

– Zend Platform JobQueue

– Memcacheq

– Relational Database

– ActiveMQ

– Storage Services:

– Amazon Simple Storage Service (S3)

– Windows Azure’s Blog Storage

– Nirvanix

– Local filesystem

When using any of the SimpleCloud APIs, your code will be portable across the various adapters provided, allowing you to pick and choose your services, as well as try different services until you find one that suits your application or business needs. Additionally, if you find you need to code adapter-specific features, you can drop down to the specific adapter in order to do so.

More adapters will be arriving in the coming months, giving you even more options!

We thank Wil Sinclair and Stas Malyshev for their assistance in the initial releases of Zend_Cloud.

Security

Several classes in Zend Framework were patched to eliminate the potential for leaking timing information from the direct comparison of sensitive data such as plaintext passwords or cryptographic signatures to user input. These leaks arise from the normal process of comparing any two strings in PHP. The nature of the leaks is that strings are often compared byte by byte, with a negative result being returned early as soon as any set of non-matching bytes is detected. The more bytes that are equal (starting from the first byte) between both sides of the comparison, the longer it takes for a final result to be returned. Based on the time it takes to return a negative or positive result, it is possible that an attacker could, over many samples of requests, craft a string that compares positively to another secret string value known only to a target server simply by guessing the string one byte at a time and measuring each guess’ execution time. This server secret could be a plaintext password or the correct cryptographic signature of a request the attacker wants to execute, such as is used in several open protocols including OpenID and OAuth. This could obviously enable an attacker to gain sufficient information to perform a secondary attack such as masquerading as an authenticated user.

This form of attack is known as a Remote Timing Attack. Timing Attacks have been problematic in the past but to date have been very difficult to perform remotely over the internet due to the interference of network jitter which limits their effectiveness in resolving very small timing differences. While the internet still poses a challenge to performing successful Timing Attacks against a remote server, the increasing use of frameworks on local networks and in cloud computing, where network jitter may be significantly reduced, raises the distinct possibility that remote Timing Attacks will become feasible against ever smaller timing information leaks, such as those leaked when comparing any two strings. As a precaution, the applied changes implement a fixed time comparison for several classes which would be attractive targets in any potential remote Timing Attack. A fixed time comparison function does not leak any timing information useful to an attacker thus proactively preventing any future vulnerability to these forms of attack.

We thank Pàdraic Brady for his efforts in identifying and patching these vulnerabilities.

Dojo Support

Zend Framework’s default Dojo Toolkit version has been bumped to version 1.5.0, which includes the new dojox.mobile component, a simple framework for client-side mobile applications.

SimpleDB Support

Zend Framework has provided support for Amazon’s Simple Storage Service (S3), Simple Queue Service (SQS), and Elastic Cloud Compute (EC2) platforms for several releases. Zend Framework 1.11.0 adds support for SimpleDB, Amazon’s non-relational document storage database offering.

Support is available for all SimpleDB operations via Zend_Service_Amazon_SimpleDb.

Zend Framework’s SimpleDB adapter was originally written by Wil Sinclair.

eBay Findings API Support

eBay has an extensive REST API, allowing developers to build applications interacting with their extensive data. Zend Framework

1.11.0 includes Zend_Service_Ebay_Findings, which provides complete support for the eBay Findings API. This API allows developers to query eBay for details on active auctions, using categories or keywords.

Zend_Service_Ebay was contributed by Renan de Lima, Ramon Henrique Ornelas, and Don Bosco Nguyen Van Hoi.

MariaDB Compatibility

Zend_Db’s mysql and Pdo_Mysql adapters are fully MariaDB compatible, and the documentation has been updated to reflect configuration options for this fork of MySQL.

New Configuration Formats

Zend_Config has been a quite popular component in Zend Framework, and has offerred adapters for PHP arrays, XML, and INI configuration files.

Zend Framework 1.11.0 now offers two additional configuration formats:

YAML and JSON.

Zend_Config_Yaml provides a very rudimentary YAML-parser that should work with most configuration formats. However, it also allows you to specify an alternate YAML parser if desired, allowing you to lever tools such as PECL’s ext/syck or Symfony’s YAML component, sfYaml.

Zend_Config_Json leverages the Zend_Json component, and by extension ext/json.

Both adapters have support for PHP constants, as well as provide the ability to write configuration files based on configuration objects.

Stas Malyshev created both adapters for Zend Framework; Zend_Config_Json also had assistance from Sudheer Satyanarayana.

URL Shortening

Zend_Service_ShortUrl was added for this release. The component provides a simple interface for use with most URL shortening services, defining simply the methods “shorten” and “unshorten”. Adapters for two services, http://jdem.cz and http://tinyurl.com, are provided with this release.

Zend_Service_ShortUrl was contributed by Martin Hujer.

Additional View Helpers

Several new view helpers are now exposed:

– Zend_View_Helper_UserAgent ties into the Zend_Http_UserAgent component, detailed above. It gives you access to the UserAgent instance, allowing you to query for the device and capabilities.

– Zend_View_Helper_TinySrc is an additional portion of Zend Framework’s mobile offering for version 1.11.0. The helper ties into the TinySrc API, allowing you to a) provide device-specific image sizes and formats for your site, and b) offload generation of those images to this third-party service. The helper creates img tags pointing to the service, and provides options for specifying adaptive sizing and formats.

– Zend_View_Helper_Gravatar ties into the Gravatar API, allowing you to provide avatar images for registered users that utilize the Gravatar service. This helper was contributed by Marcin Morawski.

Thank You!

We’d like to thank the countless contributors who have made Zend Framework 1.11.0 possible. Over 200 issues and feature requests were closed in preparation for this release, reflecting the efforts of dozens of contributors to the project.
Matthew Weier O’Phinney

Zend SimpleCloud and Azure

Josh Holmes writes a informative article on SimpleCloud here;

I’ve been playing with Zend’s SimpleCloud API for the webcast that I’m doing with Zend today. I started with the Zend Framework Quickstart tutorial but changed out the backend to hit the Azure Tables and such (well kinda – I used Zend Studio 8 Beta 2 and didn’t use the ZF tool but I still created a little guestbook). I’m going to expand this example to include blob storage and queues as well in the near future but at the moment, I’m just going to hit the Azure Tables.

To get started, continue reading.

Zend Framework 1.11.0BETA1 Released

The Zend Framework team is pleased to announce the immediate availability of the first beta release of Zend Framework 1.11.0. This release is the culmination of several months of effort by contributors and Zend Framework partners, and offers several key new features, including support for mobile devices and the first stable release of the SimpleCloud API.

You may download the release from the following location:

http://framework.zend.com/download/latest
(Note, beta releases appear separate from stable releases.)

This release is of BETA quality, and should be used for testing purposes only, not production. While the code has been well tested, we do expect there may be a few issues to resolve prior to a release candidate or general access release.

New Features in Zend Framework 1.11

Mobile Support

Zend Framework 1.11 marks the first release with explicit support for mobile devices, via the new component Zend_Http_UserAgent. This component was developed by Raphael Carles. Carles is CTO of Interakting, the digital agency of Business & Decision Group of France. Interakting employs 150 PHP professionals to build industrial PHP projects, and its clients include Canal +/Vivendi, BNP Paribas, Samsung France, Ministry of Education, Alapage (Orange), Orange Tunisia, and many others. As such, they have extensive experience in supporting mobile devices, and stepped forward to contribute to Zend Framework, which they leverage in their projects.

Zend_Http_UserAgent performs two responsibilities:

• User-Agent detection
• Device capabilities detection, based on User-Agent

The component includes a “features” adapter mechanism that allows developers to tie into different backends for the purpose of discovering device capabilities. Currently, the only shipped adapter is for the WURFL (Wireless Universal Resource File) API.

Luca Passani, author and lead of the WURFL project, has provided an exemption to Zend Framework to provide a non-GPL adapter accessing the WURFL PHP API.

Additional hooks into the component are provided via a Zend_Application resource plugin, and a Zend_View helper, allowing developers the ability to return output customized for the detected device (e.g., alternate layouts, alternate images, Flash versus HTML5 support, etc.).

Zend_Cloud: SimpleCloud API

During ZendCon 2009, Zend announced a prototype of the SimpleCloud API.
This API was to provide hooks into cloud-based document storage, queue services, and file storage.

Zend Framework 1.11.0 markes the first official, stable release of Zend_Cloud, Zend Framework’s PHP version of the SimpleCloud API. Current support includes:

  • Document Services:
    • Amazon SimpleDB
    • Windows Azure’s Table Storage
  • Queue Services:
    • Amazon Simple Queue Service (SQS)
    • Windows Azure’s Queue Service
    • All adapters supported by Zend_Queue:
      • Zend Platform JobQueue
      • Memcacheq
      • Relational Database
      • ActiveMQ
  • Storage Services:
    • Amazon Simple Storage Service (S3)
    • Windows Azure’s Blog Storage
    • Nirvanix
    • Local filesystem

When using any of the SimpleCloud APIs, your code will be portable across the various adapters provided, allowing you to pick and choose your services, as well as try different services until you find one that suits your application or business needs. Additionally, if you find you need to code adapter-specific features, you can drop down to the specific adapter in order to do so.

More adapters will be arriving in the coming months, giving you even more options!

We thank Wil Sinclair and Stas Malyshev for their assistance in the initial releases of Zend_Cloud.

Security

Several classes in Zend Framework were patched to eliminate the potential for leaking timing information from the direct comparison of sensitive data such as plaintext passwords or cryptographic signatures to user input. These leaks arise from the normal process of comparing any two strings in PHP. The nature of the leaks is that strings are often compared byte by byte, with a negative result being returned early as soon as any set of non-matching bytes is detected. The more bytes that are equal (starting from the first byte) between both sides of the comparison, the longer it takes for a final result to be returned. Based on the time it takes to return a negative or positive result, it is possible that an attacker could, over many samples of requests, craft a string that compares positively to another secret string value known only to a target server simply by guessing the string one byte at a time and measuring each guess’ execution time. This server secret could be a plaintext password or the correct cryptographic signature of a request the attacker wants to execute, such as is used in several open protocols including OpenID and OAuth. This could obviously enable an attacker to gain sufficient information to perform a secondary attack such as masquerading as an authenticated user.

This form of attack is known as a Remote Timing Attack. Timing Attacks have been problematic in the past but to date have been very difficult to perform remotely over the internet due to the interference of network jitter which limits their effectiveness in resolving very small timing differences. While the internet still poses a challenge to performing successful Timing Attacks against a remote server, the increasing use of frameworks on local networks and in cloud computing, where network jitter may be significantly reduced, raises the distinct possibility that remote Timing Attacks will become feasible against ever smaller timing information leaks, such as those leaked when comparing any two strings. As a precaution, the applied changes implement a fixed time comparison for several classes which would be attractive targets in any potential remote Timing Attack. A fixed time comparison function does not leak any timing information useful to an attacker thus proactively preventing any future vulnerability to these forms of attack.

We thank Padraic Brady for his efforts in identifying and patching these vulnerabilities.

Dojo Support

Zend Framework’s default Dojo Toolkit version has been bumped to version 1.5.0.

SimpleDB Support

Zend Framework has provided support for Amazon’s Simple Storage Service (S3), Simple Queue Service (SQS), and Elastic Cloud Compute (EC2) platforms for several releases. Zend Framework 1.11.0 adds support for SimpleDB,

Amazon’s non-relational document storage database offering. Support is available for all SimpleDB operations via Zend_Service_Amazon_SimpleDb.

Zend Framework’s SimpleDB adapter was originally written by Wil Sinclair.

eBay Findings API Support

eBay has an extensive REST API, allowing developers to build applications interacting with their extensive data. Zend Framework 1.11.0 includes Zend_Service_Ebay_Findings, which provides complete support for the eBay Findings API. This API allows developers to query eBay for details on active auctions, using categories or keywords.

Zend_Service_Ebay was contributed by Renan de Lima and Ramon Henrique Ornelas.

New Configuration Formats

Zend_Config has been a quite popular component in Zend Framework, and has offerred adapters for PHP arrays, XML, and INI configuration files.
Zend Framework 1.11.0 now offers two additional configuration formats:
YAML and JSON.

Zend_Config_Yaml provides a very rudimentary YAML-parser that should work with most configuration formats. However, it also allows you to specify an alternate YAML parser if desired, allowing you to lever tools such as PECL’s ext/syck or Symfony’s YAML component, sfYaml.

Zend_Config_Json leverages the Zend_Json component, and by extension ext/json.

Both adapters have support for PHP constants, as well as provide the ability to write configuration files based on configuration objects.

Stas Malyshev created both adapters for Zend Framework; Zend_Config_Json also had assistance from Sudheer Satyanarayana.

URL Shortening

Zend_Service_ShortUrl was added for this release. The component provides a simple interface for use with most URL shortening services, defining simply the methods “shorten” and “unshorten”. Adapters for two services, http://jdem.cz and http://tinyurl.com, are provided with this release.

Zend_Service_ShortUrl was contributed by Martin Hujer.

Additional View Helpers

Several new view helpers are now exposed:

• Zend_View_Helper_UserAgent ties into the Zend_Http_UserAgent
component, detailed above. It gives you access to the UserAgent
instance, allowing you to query for the device and capabilities.
• Zend_View_Helper_TinySrc is an additional portion of Zend
Framework’s mobile offering for version 1.11.0. The helper ties
into the TinySrc API, allowing you to a) provide device-specific
image sizes and formats for your site, and b) offload generation of
those images to this third-party service. The helper creates img
tags pointing to the service, and provides options for specifying
adaptive sizing and formats.
• Zend_View_Helper_Gravatar ties into the Gravatar API, allowing you
to provide avatar images for registered users that utilize the
Gravatar service. This helper was contributed by Marcin Morawski.

Download it today!

We’d appreciate your feedback on this release — please download and test it, and let us know what issues you encounter.

Also, please join me in extending a hearty round of congratulations to all the contributors involved in this release!


Matthew Weier O’Phinney

Using Action Helpers To Implement Re-Usable Widgets

Using Action Helpers To Implement Re-Usable Widgets

I had a twitter/IRC exchange yesterday with Andries Seutens and Nick Belhomme regarding applications that include widgets within their layout. During the exchange, I told Andriess not to use the action() view helper, and both Andriess and Nick then asked how to implement widgets if they shouldn’t use that helper. While I ended up having an IRC exchange with Nick to give him a general idea on how to accomplish the task, I decided a longer writeup was in order.

Background

The situation all started when Andries tweeted asking about what he considered some mis-behavior on the part of the action() view helper — a situation that turned out not to be an issue, per se, but more a case of bad architecture within Zend Framework. His assumption was that calling action() would fire off another circuit of the front controller’s dispatch loop — which would mean he could rely on plugins he’d established to fire. However, action() does nothing of the sort. It instead pulls the dispatcher from the front controller, and manually calls dispatch() on a new action. As such, action helpers will trigger, but no front controller plugins will. Additionally, if a redirect or “forward” condition is detected, it simply returns an empty string.

The helper was done this way because Zend Framework does not render views a single time — it instead renders after each action, and accumulates views to render in the layout. If we were accumulating view variables and rendering once, and if we were using a finite state machine of some sort, we could probably operate the way one would expect — within the dispatch loop. Since we don’t, any solution around looping over actions (such as the ActionStack action helper/front controller plugin) or rendering the content of executing an action will be a hack. Note: ZF2’s MVC layer may make this possible… though still not necessarily recommended.

There are other reasons to avoid the use of these solutions, though. If you are invoking additional controller actions in order to help populate your view, you’re likely putting domain logic into your controllers. Think about it. The controller should only be responsible for taking the input, funneling it to the correct model or models, and then passing information on to the views

With that in mind, here’s the approach I recommended to Nick and Andries.

The Secret Weapon: Action Helpers

I’ve blogged about action helpers before. They’re a built-in mechanism in Zend Framework to allow you to extend your action controllers in a way that uses composition instead of inheritance.

One approach to widgets for Zend Framework makes use of these. Consider the following “user” module:

via read more.

High Scalability – More Troubles with Caching

As a tasty pairing with Facebook And Site Failures Caused By Complex, Weakly Interacting, Layered Systems, is another excellent tale of caching gone wrong by Peter Zaitsev, in an exciting twin billing: Cache Miss Storm and More on dangers of the caches. This is fascinating case where the cause turned out to be software upgrade that ran long because it had to be rolled back. During the long recovery time many of the cache entries timed out. When the database came back, slam, all the clients queried the database to repopulate the cache and bad things happened to the database. The solution was equally interesting:

So the immediate solution to bring the system up was surprisingly simple. We just had to get traffic on the system in stages allowing Memcache to be warmed up. There were no code which would allow to do it on application side so we did it on MySQL side instead. “SET GLOBAL max_connections=20” to limit number of connections to MySQL and so let application to err when it tries to put too much load on MySQL as MySQL load stabilizes increasing number of connections higher until you finally can serve all traffic without problems.

Peter also suggested a few other helpful strategies:

  • Watch frequently accessed cache items as well as cache items which take long to generate in case of cache miss
  • Optimize Queries
  • Use a Smarter Cache
  • Include Rollback in Maintenance Window
  • Know your Cold Cache Performance and Behavior
  • Have a way to increase traffic gradually
  • Consider Pre-Priming Caches

via more.

You want to do WHAT with PHP? Chapter 10

With the book out and released I now reach the final chapter excerpt that I will have. As I said in one of my previous chapter excerpts, I did not write this book to cover a wide range of topics. I wrote it to cover a narrow range of topics, more fully. But the topics I chose were based off of my experiences as a Zend Consultant for several years. If you are someone with 2-5 years of experience (the typical requirement for a PHP job) you need this book. This book was born out of my experience dealing with code written by people with 2-5 years of experience, sometimes more.

This chapter is called “Preparing for success, preparing for failure”. It contains a few pseudo-rules that can go a long way to helping you manage unexpected popularity of your website. In other words, to help you in minimizing the effects of 2-5 years of programming experience. 🙂 Those rules are not complete and there are plenty of exceptions, but knowing these things will help you be more prepared for handling things like load and failure.

via You want to do WHAT with PHP? Chapter 10.

You want to do WHAT with PHP? Chapter 9

e_schrade writes; There is a bunch I could say to introduce this chapter.  However, I think that by reading the first few paragraphs you will know what I’m talking about.  For those who are experienced developers some of these items might seem a little basic, but there are reams and reams of PHP developers who do not follow several of these rules.

In other news, “You want to do WHAT with PHP?” is now available for purchase in the Amazon store.

Chapter 1: Networking and Sockets
Chapter 2: Binary Protocols
Chapter 3: Character Encoding
Chapter 4: Streams
Chapter 5: SPL
Chapter 6: Asynchronous Operations with Some Encryption Thrown In
Chapter 7: Structured File Access
Chapter 8: Daemons
Chapter 9: Debugging, Profiling, and Good Development
Chapter 10: Preparing for Success

via Read part of chapter 9.

Zend_Log with multiple writers

eschrader writes; So I was sitting here thinking to myself “This is Friday and I’m not getting much of anything done.  Maybe I should write another Friday Framework Highlight.”  I figured that it was a good idea so I pondered what I should write.  I came up blank and so I asked Matthew Weier O’Phinney.  “Multiple writers for Zend_Log,” he said.  I agreed.

If you were not aware, Zend_Log provides facilities for writing to multiple logs through the same log instance.  Additionally, you can do this via configuration options when using a Zend_Applicatin resource plugin.  Together those make for very powerful logging mechanisms.  “How?” you ask?  It’s really easy.  Take your application.ini file, which you use to configure your Zend_Application instance, and make it look something like this.  I’ll highlight the pertinent parts

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.log.stream.writerName = "Stream"
resources.log.stream.writerParams.stream = APPLICATION_PATH "/logs/application.log"
resources.log.stream.writerParams.mode = "a"
resources.log.stream.filterName = "Priority"
resources.log.stream.filterParams.priority = 4

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.log.stream.filterParams.priority = 7
resources.frontController.params.displayExceptions = 1
resources.log.firebug.writerName = "FireBug"
resources.log.firebug.filterName = "Priority"
resources.log.firebug.filterParams.priority = 7

What this does is say that “in production, log warnings and above to the log file, but in development, log debug to the log file AND send the log items to FirePHP.”  Then, in our index controller we put this:

class IndexController extends Zend_Controller_Action
{

public function indexAction()
{
$this->getInvokeArg('bootstrap')->log->debug("I'm at indexAction");
}

}

When we execute this code we get both the output in the application log

$ tail -f application.log
2010-09-10T16:27:25-05:00 DEBUG (7): I'm at indexAction

and in the Firebug log

X-Wf-Protocol-1            http://meta.wildfirehq.org/Protocol/JsonStream/0.2
X-Wf-1-Structure-1    http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1
X-Wf-1-Plugin-1            http://meta.firephp.org/Wildfire/Plugin/ZendFramework/FirePHP/1.6.2
X-Wf-1-1-1-1            122|[{"Type":"LOG","File":"C:\\workspace\\Test\\application\\controllers\\IndexController.php","Line":8},"I'm at indexAction"]|

In production we wouldn’t get anything since this code would filter out debug logging, due to the resources.log.stream.filterParams.priority setting in the production section in application.ini.  Simple.  Done.

via e_schrade.

Zend_Server Class

e_schrade wrote a neat way of doing things in the service layer; Let’s take a quick look at something that’s kind of neat in Zend Framework. I’ve been doing some work with Adobe on some articles and one of them was on working with mobile clients with Flash. Well, me being the masochist I did more. What I did was write an example that worked as a full website, an Ajax website, a Flash service and an XML-RPC service.

Looks like a lot, right?  Actually there’s not much there.  Here’s the logic flow.

  • Is it an XMLHTTP Request and is it a POST? Create the Json server
  • Is it an AMF request? Create the AMF server
  • Is it an XmlRpc request? Create the XmlRpc server
  • Is it an XMLHTTP Request and is it a GET? Create the Service Map (for JSON-RPC 2.0)
  • If a service handler has been created add all of the application’s mappers, attach the service handler to the request and redirect to the service action.

And with that you have an application that can serve content for multiple different types of service with almost no effort on your part.  At least.. if you copy and paste this code.

Have a good Friday!!!

via Zend_Server – zf ffh zend_server on e_schrade – zend php.

Finding syntax errors in your PHP Project files

Till posted this little snippet;
It’s so useful I just had to share it 🙂

find . \( -name "*.php" -o -name "*.phtml" \) -exec php -l {} \;

Just go to your project directory and fire it off, it will help you find those pesky unmatched {}