Zend Framework is hard. It wasn't built as an entry level framework, knowledge of the concepts involved is assumed1. That said, the first requirement for Zend Framework 2.0 is to make it a little bit easier:
Ease the learning curve
In late 2009, we did a survey of framework users to determine what they use,
what environments they use, and what their needs are. The top issue, bar none,
was the difficulty of learning the framework. Some of these issues include:
- Difficulty in the "first hour" with the framework.
- Uncertainty about the "next steps" following the quick start.
- Inconsistent APIs in the source code itself. One component may use "plugins," another "helpers," and yet another "filters."
- Uncertainty about where extension points exist, and how to program for them.
- Confusion over whether they can use Zend Framework only as an MVC stack or as individual components.
So it's not just you, it's hard for everyone - read the whole wiki page, there are quite a few things that are identified as unnecessarily complex. But even if the above requirement is fulfilled, still it won't become an entry level framework, meaning that it's not a framework you should be learning on, but one that you should be using when you've actually understood the concepts involved.
Since you are still learning, it would be a lot more valuable to build your own MVC architecture. Rasmus Lerdorf's notorious2 "The no-framework PHP MVC framework" blog post gives a very simple and clean example of MVC through procedural PHP, without any framework or other third party library involved.
But if you really want to learn with a framework, you should consider a micro framework instead of a full blown one. Slim has a very small, clean and thoroughly tested code base and it should be ideal for learning. I haven't played around with any other micro framework, you should do your own research and decide which one is better for you.
And for a quick and dirty introduction to routing, see my answer to this question. It's not a very hard concept to grasp, but Zend Framework does make it look like a lot more than it actually is.
1 The best description I've read for ZF is that's it's a framework building framework, not an application framework. It's raw power and extreme list of features aren't suitable for small to medium websites. Unfortunately can't really find where I read that.
2 Read disclaimer at the top of the blog post.
Update, inspired by @Karpie's comment:
A framework is not supposed to be hard, the whole point of a framework is to make things easier. It's possible that even with a firm grasp of the concepts involved, ZF is not a good fit for you.
There are a lot of subjective factors involved when choosing a framework, and unless every other framework lacks functionality you absolutely need - and can't write on your own, you should avoid ZF and use a framework that feels more natural to you.
If you know the concepts, the framework shouldn't be getting in the way.
(Disclaimer: I don't know any of the technologies mentioned in the question; I'm just inferring from the descriptions on the question itself and the linked articles.)
Dependency and the order of execution. Based on the linked documentation,
- It seems you can control the order of execution of middlewares simply by calling
app.use(...)
in a particular order.
- It can be documented clearly inside your project.
- There is a way to make it work correctly; whether it can be done in a maintainable (non-fragile) way is a matter of
- Your design, and
- Your (or programmer's) discipline in following the guidelines
There are some relevant design patterns and techniques that will help you maintain the correct dependency and order of execution.
- Command pattern
- Chain of responsibility pattern
- Decorator pattern
- Topological sorting, which can be used to calculate the order of execution based on their dependencies. You will likely do this with pen and paper, since you have control over what middlewares will be executed and there are no new middlewares to be added.
Regarding "monkey-patch(ing) the response object",
- A middleware that is executed early can insert some placeholders in the response, which will be replaced by real content by another middleware that is executed later.
- There can also be a final middleware that strips out any placeholders that were unprocessed (i.e. as a catch-all in case of a programming mistake), and replace that with error message.
- To prevent injection attacks (the user somehow manipulating user-submitted content to look indistinguishable from a placeholder), you can sanitize (remove) such placeholders from the response in the beginning, before any genuine placeholders are added.
- Anything else that do not belong to the response might be better written to the request object, or the session middleware instead.
To resolve circular dependencies between middleware, one can implement a middleware that would be executed at the very beginning. This middleware can do a "requirements gathering" on the request, to decide what other middleware will be potentially activated, and then set various flags on the request object.
This "requirements gathering" middleware should avoid doing the actual work that causes the circular dependency.
The authentication issue is not unique to any paradigm. It is a general user interface design issue that affects every application where the user doesn't need to authenticate up-front.
The core issue is this. After the user navigated to a page, and that page contains elements that will potentially require authentication, the questions are:
- How to let the user easily find out whether the app is in an authenticated state or not (i.e. let the user see whether it's "logged in" or not)
- How to convey to the user that there are such elements (that would require authentication)?
- Completely hiding it?
- Show a pane that blurs over it (but still hints at the existence of what's below), and put a login button on top? (There would be no user-specific information in the blurred content.)
- Show the element with placeholder strings
- Should the user be forced to authenticate? If so,
- Should this happen when the page is being loaded?
- Or only when the user clicks on the element (or a "Login" button?)
- Are there less intrusive ways to authenticate the user?
- Will this compromise security? Does the benefit outweigh the risks?
Best Answer
From my understanding of hooks this is true. The way I understand hooks it that you can execute some code at a predefined point during the execution flow. Afterwards the application continues as if nothing happened. This is very abstract so I would like to express this using an example:
Lets say you can execute code when an
before_authentication
hook is encountered. Maybe you would like to initialize sessions before authentication and would therefore do this here. This can also be done through middleware.Lets say you have a middleware component which handles authentication. Each middleware is defined inside an array and are executed in the defined order. You would then insert your
InitializeSessionMiddleware
component just beforeAuthenticationMiddleware
is defined in the array.Both of these solutions would work, but since Slim (AFAIK) is very HTTP focused, it would be more appropriate to write this as middleware.
Please keep in mind this is my understanding of midddleware and hooks. If you would like to modify how the application works at predefined points, I would look into exposing some callbacks, which has a predefined structure (interface?) unique for that specific point. This callback could be changed if the structure is correct.
I hope this can help you, happy coding.