Let's Talk - Building a Modular PHP Framework part 2

Author(s): Louis Ouellet


Time for part 2! In our previous part, we set up the groundwork of our modular PHP framework. This time, we will focus on expanding its capabilities to support the following objectives:

  • Add support for extensions
  • Begin implementing a Command-Line module
  • Add support for models to be used to create shared methods that require a database
  • Add support for helpers to be used to create shared methods that do not require a database

These enhancements will provide the flexibility we need to build modular, maintainable, and extensible applications. Let's walk through each update step by step.

Updating the Bootstrap

We will begin by updating our Bootstrap class to include helpers and models. We have also changed the default class for CLI to LaswitchTech\Core\CLI so that we can start working on it before exporting it into its own module.

Source: Bootstrap.php

Updating the Request Class

Next, let's update the Request class so it can handle command-line arguments. In the constructor, we store the global $argv in an Arguments property (with a default empty array).

Source: Request.php

We then add a getArguments() method for retrieving the arguments, and move any existing user-input retrieval methods (previously in coreCLI) into this class.

Updating the Output Class

We also need to update the Output class to handle both browser-based output and command-line output. Below is an example of how to handle CLI detection (STDIN) and color-coded messages.

Source: Output.php

Implementing Helpers

Helpers provide small, shareable methods. To achieve this, we first create a base Helper class that can be extended if we need shared properties or methods in the future.

Source: Helper.php

Next, we implement the main Helpers class to dynamically load individual helper files from both your application and any plugins.

Source: Helpers.php

Implementing Models

Models behave much like Helpers, but differ in that they usually require a database connection. We store a reference to the global $DATABASE object in the base Model class.

Source: Modal.php

Just like Helpers, the Models class dynamically loads all models from your /Model folder and plugin directories:

Source: Modals.php

Implementing the Command-Line Module

To implement a command-line interface (CLI), we'll create a template Command class for developers to extend. Then we'll add a CLI class that identifies and executes commands and actions.

Base Command Class

Source: Command.php

CLI Class

Source: CLI.php

Testing the Code: Creating a "debug" Plugin

Let's create a simple plugin named debug in /lib/plugins/debug/Command.php. This demonstrates how to define custom commands to be handled by our new CLI infrastructure:

Source: Command.php

Running the CLI

Below is a sample script debug.php in a tmp/ folder to test the CLI. Make it executable (chmod +x tmp/debug.php) and run it like so: ./tmp/debug.php debug execute

Source: debug.php

Example Output

When you run:

./tmp/debug.php debug execute

You should see something like:

Variable Name: BOOTSTRAP = LaswitchTech\Core\Bootstrap
Variable Name: REQUEST = LaswitchTech\Core\Request
Variable Name: CLI = LaswitchTech\Core\CLI
Variable Name: CONFIG = LaswitchTech\Core\Config
Variable Name: LOG = LaswitchTech\Core\Log
Variable Name: OUTPUT = LaswitchTech\Core\Output
Variable Name: NET = LaswitchTech\Core\Strap
Variable Name: HELPER = LaswitchTech\Core\Helpers
Variable Name: DATABASE = LaswitchTech\Core\Strap
Variable Name: MODEL = LaswitchTech\Core\Models
Variable Name: LOCALE = LaswitchTech\Core\Strap
Variable Name: SLS = LaswitchTech\Core\Strap
Variable Name: SMS = LaswitchTech\Core\Strap
Variable Name: SMTP = LaswitchTech\Core\Strap
Variable Name: IMAP = LaswitchTech\Core\Strap
Variable Name: INSTALLER = LaswitchTech\Core\Strap
 
Host: localhost
 
Parameter:
 
CLI:
Debugging...
 
End of Script

Conclusion

GitHub Repository

GitHub Repository - v0.0.7

In this second part of our series, we expanded our modular PHP framework to support command-line operations, helper classes, and models. By creating a generic CLI class and a template Command class, we can easily extend the framework with new commands and actions. The addition of Helpers and Models provides a cleaner, more organized way to share code across your application—making it easier to maintain and extend functionality without duplicating code.

Our framework is starting to take shape with clear separation of concerns and the flexibility to add or remove features as needed. In upcoming parts, we will continue to refine our framework, possibly by integrating more robust logging, configuration management, and additional modules that can further streamline development.

Tags

Discussion

Enter your comment. Wiki syntax is allowed:
K X M J F