Application Architecture

Application architecture is the set of structural decisions that determine how your code is organised, how components communicate, and where responsibilities sit. In the context of PHP and the Zend Framework Book, this means the MVC pattern, the front controller, the bootstrap process, the model layer, and the separation between presentation, business logic, and data access. These decisions have more impact on the long-term maintainability of a codebase than any individual feature implementation.

The MVC Pattern

Model-View-Controller divides an application into three layers. The model handles business logic and data. The view handles presentation. The controller sits between them, accepting input, delegating to the model, and selecting a view to render the result.

In Zend Framework 1, this plays out through Zend_Controller_Action subclasses (controllers), Zend_View scripts (views), and your own domain classes (models). The Architecture chapter explains how these layers interact through the front controller and dispatch loop. The Hello World Tutorial shows MVC in practice with a simple working example, and the Blogging Application chapter extends that into a more complete implementation.

MVC is not the only viable architecture for PHP applications, but it is the one that ZF1 implements and the one that most PHP frameworks have adopted in some form. Understanding it properly means understanding that the controller should be thin. It coordinates, it does not contain business logic. That distinction is the root of the “fat controller” problem that the Refactoring Fat Controllers in PHP guide addresses.

The Front Controller

The front controller pattern routes every HTTP request through a single entry point. In a Zend Framework application, that entry point is index.php in the public directory. Apache’s mod_rewrite (covered in the Apache topic hub) sends all non-file requests to this script, which boots the framework, runs the router, determines which controller and action to invoke, and dispatches the request.

This pattern gives you a single place to initialise shared resources, register plugins, configure error handling, and set up the environment. The alternative, having multiple entry point scripts for different parts of the application, was common in older PHP projects but leads to duplicated setup code and inconsistent behaviour.

The glossary entry for Front Controller defines the pattern, and the Dispatch Loop entry explains the iteration mechanism that allows forwards and redirects within a single request.

The Bootstrap

Bootstrapping is the initialisation phase where the application sets up everything it needs before handling a request. In ZF1, Zend_Application standardises this through resource methods that configure the database adapter, session handler, view renderer, router, and other services.

The Bootstrap chapter walks through this process in detail. The principle behind it, setting up all shared resources in one place during a defined phase, is the same principle that modern dependency injection containers formalise.

Service Layers and Dependency Injection

As applications grow, the controller-calls-model pattern breaks down. Controllers start accumulating logic that does not belong in the model layer: sending emails after a form submission, logging events, coordinating between multiple models, applying authorisation checks. A service layer sits between the controller and the model, encapsulating these workflows.

Dependency injection is the technique that makes service layers practical. Instead of a service class instantiating its own dependencies, those dependencies are passed in from outside, typically through constructor arguments. This makes each class easier to test (you can pass in mocks or stubs) and easier to change (swapping an implementation means changing the wiring, not the consuming code).

Zend Framework 1 did not have a formal dependency injection container, though ZF2 introduced the ServiceManager for exactly this purpose. The patterns discussed in the Model chapter and Domain Model chapter show the early stages of this thinking: separating domain objects from persistence, passing mappers into service classes, keeping the layers distinct.

The Refactoring Fat Controllers guide walks through the practical process of extracting service layers from existing controller code.

Domain-Driven Design Concepts

The book’s model chapters draw on domain-driven design concepts, even without using that label explicitly. Entities with identity, value objects, the distinction between domain logic and persistence logic, and the use of data mappers rather than active record, these are DDD building blocks.

The Data Mapper glossary entry defines the pattern used in the book’s model implementation. The Persistence Layer entry covers the storage abstraction that sits beneath the domain model.

For applications that have grown complex, thinking in terms of bounded contexts, aggregates, and explicit domain models provides a framework for managing that complexity. The book’s approach to the model layer is a practical starting point for that kind of thinking.

Glossary Terms

See Zend Framework for the full chapter listing, PHP for language-level features that support these patterns, Laminas for how the architecture evolved in the successor framework, and Performance for the performance implications of architectural decisions.