The mystery of missing Form->getData() values in Zend Framework 2

After taking a short break from Zend Framework 2 I started working on a new project in it. I created a Form class that looks like:

The problem arose when I validated the form and tried to access the data in the controller:

However, for some reason, the output of $data was missing values, something of this sort:

So, the getData() keys were present, but values were missing!

It took me a while to figure out what’s going on. In order to validate the form, Zend Framework 2 calls getInputFilter on it. However, it does not store the resulting InputFilter, but rather calls this method again whenever it needs it – essentially overwriting any data put into it by $form->setData($postData);

The solution was to store form’s InputFilter as a static variable. The code now looks like this and behaves as expected:

Output of getData() looks like:

Looks like a bug at the first glance, but I suppose this behavior allows for bigger flexibility when validating forms. I still have to find the good use for it, but oh well…

When Gunicorn fails, but runserver works

Sometimes I am cheating on PHP with Python (PHP knows and it doesn’t appear to mind). I was developing a Django project and it worked perfectly with manage.py runserver but when run through Gunicorn it was failing with an ImportError.

This really got me worked up – as a programmer, I hate when I don’t understand why something would work in one environment but fail in another.

The problem was circular import in Python!

I had two apps in this project: news and comments. News had the following model:

Comments had something like this:

This worked perfectly well with Django’s built in server, but failed when I tried to run it through Gunicorn. For some reason, this kind of circular import just doesn’t work with it! I am still trying to figure out why, but meanwhile, the fix was to reference ForeigKey with a string. Now I don’t have the offending import in comments/models.py and I reference the foreign key like this:

Magic of Mysql’s GROUP_CONCAT()

I lived for a long time without knowing about this function, but it is really great when you need to create quick reports.

E.g. imagine that you have three tables:

Users table:

Clubs table:

And a many-to-many relationship table:

What if you needed to see which user belongs to which group, in a human readable format? You could write a query like:

But the result will be messy (though easy to parse for a program afterwards):

If you want to have an instantly human-readable result, you can utilize GROUP_CONCAT() like this:

Much nicer, isn’t it? Beware, this is not standard SQL and it won’t work in e.g. PostgreSQL, but you can utilize something like this in it:

PHP Framework Comparison: which one to use in 2014?

PHP as a language is maturing and frameworks surrounding it seem to be following the trend. The first generation of frameworks, those built around PHP 4 are now long forgotten and nobody seems to remember the time when use of classes was impossible (or discouraged when possible) using our favorite language. The second generation was mostly centered around solid object model introduced by PHP 5 and included widely deployed tools such as CodeIgniter, Zend Framework 1 or Symfony 1.

While CodeIgniter silently died away, folks around Zend Framework and Symfony decided to rewrite their tools and learn from their own mistakes. Many frameworks have appeared during this exciting period of PHP development. They all introduced some new thinking to PHP: namely, design patterns are now used more prominently and there is a lot of attention on abstracting object creation. This means that instead of standard $obj = new Class(), a different approach is taken with Abstract Factories, object composition, etc.

When a colleague and I were tasked to find a framework to start a new PHP project in 2014, we couldn’t possibly review each one of them and making an informed decision was bound to disregard a good number of good frameworks.

For example, we didn’t review FuelPHP. While this framework has a lot of going for it – namely simplicity and good documentation, we also remembered the issues surrounding their plan to release a version 2 which became vaporware, which (probably unfairly) gave us a reason to eliminate it.

We also shied away from CakePHP, which is proved by years of existance, but seemed overly kitchen-sinkish in its approach. Some frameworks like Yii, while obviously solid, we had to skip because there wasn’t enough hours in a week to review it properly.

So, after some research, we decided to review the following frameworks:

  • Zend Framework 2 – I have worked with Zend Framework 1 and have extensive experience with the new release. I can’t say I am too happy with it, so while I wouldn’t terribly mind using it for a new project, I would rather poke an eye out than have to create a new module in it.
  • Symfony 2 was an obvious contender because we have used parts of it before. Like Zend, Symfony is very modular and you can use bits and pieces included in it without using the entire framework. This means that I already had a lot of experience with Doctrine, which Symfony relies upon for ORM.
  • Laravel seems to be framework du jour, a sort of a new CodeIgniter, with a low learning curve. It’s based on some Symfony modules, so it wouldn’t be completely unproven. Also, Facebook HHVM seems to support it fully, which goes to show that it is taken seriously by a wider audience.
  • Phalcon is another trending framework with a primary selling point of being written in C (PHP modules can either be native, written in PHP, or written in C, like most low level modules are) which gives it a nice speed advantage.

Our project is a simple one: an e-commerce site with a twist – we want to sell t-shirts and give affiliates a lot of control. We would be prototyping this site, meaning that we would adopt an agile approach, first developing a prototype and extending upon it in iterative development, as opposed to the traditional systems life cycle which would assume strict planning and full specification before start of development.

Our requirements and review points:

  1. rapidity of development,
  2. scalability,
  3. performance,
  4. ability to write modular code and
  5. quality of documentation.

Some requirements were obvious, like unit testing capabilities, which most modern frameworks support nicely. We wanted to make sure the framework is feature-complete so we could concentrate on concepts and not worry about e.g. how to store a session to the database. Other things were completely irrelevant, like ease of deployment (we are not among the shared hosting crowd, which would disqualify Phalcon immediately).

Zend Framework 2 was the first on the desk. I have built a couple of largish projects in it so it was my call to determine what is good and what is not about it.

Zend Framework 2 positives were:

  • Modularity is perfected in it – it has beautiful ways to make your code modular and forces you into good design patterns to make it so.
  • Things are abstracted away beautifully in this framework, which means you have a lot of control over everything. For example, if you want your controller to have access to particular libraries and models, you create a factory for it so when it’s loaded all dependencies are ready. Most frameworks nowadays use this approach, known as dependency injection, but Zend revolves around it.
  • Modules exist for a lot of things, which is always nice. However, most modules aren’t very mature so you won’t find a solution to every problem there, or you will have to reinvent the wheel because module’s author didn’t write it in the way that you would like.
  • Some things are very well thought out: for example for each session container you can define its time-to-live and number of hops (page requests) it will last. So you can create a custom “flash messenger” which will last for 1 post page request by doing:

Unfortunately, Zend Framework 2 has some negatives too:

  • I gave you an example for setExpirationHops method of \Zend\Session\Container. I know about it because I dug into the code of one of Zend’s controller plugins. It was documented for the first version of this framework, but I dare you to find it in new documentation. It’s not there, and it should be. It is in API documentation, but the information is skimpy to say the least. Documentation is written in a tutorialish manner, meaning information is dumbed down and simplified and lacks a lot of important stuff.
  • So, the only way to really learn it is to browse the code. I said that Zend does a great job of abstracting things away and letting you program by contract, but try digging into its code and you will find it hard to follow. The execution of code isn’t linear, it rather depends on events and forces you to adhere, so it’s very hard to follow what part of code is calling which event and what kind of magic happens to every object in the execution flow.
  • There is no ORM implemented out of the box. While there is a solid query builder and ways to interact with database, if you want ORM you need to use third party modules.

The biggest drawback to Zend Framework 2 is that it is incredibly verbose. To create a controller, in most frameworks you would drop a class in a controllers’ directory and it would be available. In Zend, you will do that, but also have to tell the service manager (which handles the creation of every object) where it is and if it has any dependencies.

Configuration is complex and allows for a lot of customization, but when you are writing configuration files, you are returning arrays and there is no autocompletion in your IDE for it. So, you have to search through (bad) documentation to figure out how to do it. Documentation often recommends this approach in which you pass big arrays to factories, but it’s not a favor to developers.

Combine this verbosity with a simple matter of fact: when you use factories to create objects, your IDE will not know how to autocomplete anything. E.g., this is a piece of code that you will write a lot, despite the fact that Zend developers recommend against it:

Otherwise, how does your IDE know what $obj is? How does a developer inheriting your code, or you after a month, have any idea what $obj is? A bit ugly… A better solution to this is to handle your depending objects with dependency injection, but verbosity of doing that will discourage you and you will always fallback to abusing serviceLocator for everything. Symfony2 has this solved much better with it’s configuration files.

Symfony 2 leaves a different type of impression. While Zend Framework 2 feels over-engineered, written by people who know a lot about PHP but have developed very few sites in it, Symfony 2 feels very natural and has a solution to most common problems.

Some clear advantages emerged for Symfony 2:

  • Symfony is feature rich. Both Zend and Symfony have a kitchen-sink approach, but Zend is much lower level. For example, Symfony offers a way to manage your assets practically out of the box. While you can find similar modules for Zend Framework 2, they are third party. This may sound like a so what? situation, but there is a crucial difference: using bundled modules (or bundles in Symfony 2 lingo) will force you into respecting the grander design of the framework. Also, if there is one official way to accomplish a task, tomorrow, when you hire a new developer, they will have little doubt in what the approach was. This advantage goes a long way sometimes.
  • The structure and code is very intuitive. E.g. if you are reading the tutorial about parsing forms, you will notice that the example given binds the form to a model class. You will quickly come into a situation when there is no model to bind and Googling “how to create a form without a model class” will give you just the right information. Folk behind Symfony 2 clearly gave a lot of thought to what developers need, and that’s great.
  • There is a great support for modular development by using bundles.

There was some bad stuff about Symfony 2 as well. Namely:

  • It takes learning. Documentation is quite useful, but very tutorialish, while I would much prefer a heads first approach. You can’t dive into development without spending some hours reading first so you can figure out how to do it properly. Of course, this can be a good investment of time because it forces you into best practices, but I am sure it could be done better.

After reviewing Symfony 2, we started looking into Laravel. Laravel uses some components of Symfony 2, and it is hyped about the Internet a lot. Most people who really like it quote its ease of use.

Advantages of Laravel were:

  • Easy learning curve and clear documentation, insomuch that it resembles CodeIgniter. Documentation is very important and both those frameworks got it right: divide it into discreet tasks that developers care about (e.g. how to handle sessions, or how to to authentication), explain it succinctly and completely. I wish other frameworks did this as well.
  • Sane approach to development and easy to get started.

Disadvantages were:

  • Confusing ecosystem and lingo: I don’t understand why developers can’t just use well established terminology. For example, what’s wrong with calling the ORM – ORM? How does this make sense to a newcomer: class User extends Eloquent {}. What is “Eloquent” and why do I have to look it up?
  • A lot of logic that should belong to a controller is defined in routes. For example, the documentation suggests you should hint which controllers and actions should be available to non logged in users by customizing your routes configuration. This seems rather out of place to me and goes against loose coupling principle.
  • Caching abilities seem to be quite limited.
  • There is no support for traditional modules. You can work with packages, but they are targeted at vendors. You can’t easily group your controllers, models and views into logical groups.

The biggest disadvantage was that everything is hidden behind a facade. This means that they use standard dependency injection for a lot of things, but then hide it behind a facade with magic methods. E.g. you write code like:

Session actually does not implement someMethodCall, but rather uses a magic method to call some form of: $di->get(‘session’)->someMethodCall(). This is pointless and wrong for many reasons, not least the fact that, again, there is no autocompletion for your IDE (you can do it via a third party package though). Also, while most of the Laravel’s code is namespaced, facade classes aren’t! Perhaps there is a good reason for this, but to me it was confusing.

There are other, very minor, issues I had with Laravel: inconsistency of using namespaces and dreaming up words to represent functionalities (Illuminate, Eloquent, etc.) are one of them. But also, blatant disrespect for FIG standards and different coding styles for example code wasn’t to my liking.

Overall, Laravel seems nice. However, it’s also recipe for disaster. Just like PHP allows novices to write atrocious code, and attracts novices because of the low learning curve, so does Laravel use some anti-patterns and attracts newcomers because it has great documentation. In the right hands, Laravel can be a good framework, but in the wrong (most) hands, it will cause unmaintainable code good only for hobbyist projects.

Finally, after traditional frameworks were exhausted, I installed Phalcon and gave it a spin.

It’s fast. Very fast: under 1 ms calls on my machine for most controllers without database calls. But you don’t code without database calls, so in the end, it won’t do a tremendous amount of difference.

I can’t say a lot about Phalcon. E.g. form helpers for radio html fields were only introduced recently to it (version 1.3), so it’s still in heavy development. Custom routes didn’t come until version 0.4, which gives you a state of maturity.

When it comes to its design, it kind of resembles Zend Framework 1 in its functionality but utilizes dependency injection heavily and openly, so it follows the trend.

I like it a lot, but I think I will wait for a couple of years before I know it’s not vaporware.

So, to summarize:

  1. For rapidity of development Laravel wins hands down. But down the road, you will hit the ceiling of its capabilities quite soon. Zend Framework 2 loses heavily, with Phalcon being very easy to get started with and crank out code. Symfony 2 is balanced somewhere in between Phalcon and Zend.
  2. Scalability goes to Zend Framework 2 and Symfony 2. When I say scalability, I talk about scalability of code – developing a true enterprise application. Their excellent modular design and great unit testing integration lets you really build upon the code.
  3. Performance goes to Phalcon, but Facebook’s HHVM runs Laravel just fine which would make it just as quick.
  4. Modularity goes to Zend Framework 2 and Symfony 2. Phalcon doesn’t lack there too much, but it’s not as highly polished.
  5. Quality of documentation is in a way a matter of personal taste. I really like Laravel’s approach to concise and complete, broken down, sections explaining common tasks.

Overall however, I think that Symfony 2 is the way to go.

PHP SoapClient Through SOCKS Proxy

I often find myself in the following predicament: a service that I am using allows me to access it only through a registered IP address. For example, if you want to use Stamps.com to generate postage labels to automate shipping goods, they will ask you to provide a production and a testing IP address. They will only allow you to connect to their SOAP service if it originates from that particular IP address.

The problem is that I am behind a dynamic IP, so if I develop from my local machine I won’t be allowed to connect to the SOAP service at all since there is no point in sending them a request to change the whitelisted IP whenver my ISP decides to issue me another address. Also, developers come and go, and even if they have static addresses, it’s still a pain in the butt to continually request that new IP addresses get whitelisted and old ones removed.

To remedy this situation, we got our “preview” server whitelisted for development. Preview server is used to automatically pull all commits to our subversion repository and always keep the latest development version of the site available for testing. This server has a static IP address. Now, whenever I want to make requests to the SOAP server from my local machine, I proxy all requests through the “preview” server. Here is how to do it using SOCKS proxy:

Firstly, you need to create a ssh tunnel to the server which has the desired IP address. Assuming you are using Linux (or some other flavor of UNIX, like FreeBSD or Mac OS X), this command will allow all traffic going to 1080 to be proxied through whitelisted.server.com. Of course, you must have a ssh account available on the target server

ssh -p 22 -N -D 1080 whitelisted.server.com

-p 22 specifies the port number for SSH connection, while -D 1080 specifies the port that you will be using for proxying the traffic. You can use anything other than 1080, it’s up to you. You can also pass -f parameter so the command will execute in the background, but for that you have to have passwordless login enabled (e.g. use your RSA key to login). Once the tunnel is established (it will look like any other ssh connection), keep it open whenever you need to proxy the traffic.

Now, you need to tell PHP SoapClient to use this proxy.

Your regular code may look something like:

We have to extend SoapClient and use the new class to be able to utilize the proxy:

Voila! We have overriden the method __doRequest to use curl extension to make the HTTP request through proxy and all your requests will now appear to come from the “preview” machine.

1 2