A PHP MVC framework with invokable controllers (Actions), Views are classes for data manipulation before rendering Templates, Models are partitioned between DAO and DTO objects. And Modular separation, similar to Django apps.
Go to file
2025-12-14 20:09:06 -06:00
.github/workflows initial commit 2025-12-14 17:10:01 -06:00
bin initial commit 2025-12-14 17:10:01 -06:00
src Router groups, Configs 2025-12-14 20:09:06 -06:00
tests Router groups, Configs 2025-12-14 20:09:06 -06:00
.editorconfig initial commit 2025-12-14 17:10:01 -06:00
.env.example initial commit 2025-12-14 17:10:01 -06:00
.gitattributes initial commit 2025-12-14 17:10:01 -06:00
.gitignore initial commit 2025-12-14 17:10:01 -06:00
composer.json initial commit 2025-12-14 17:10:01 -06:00
LICENSE Initial commit 2025-12-09 21:32:51 +00:00
MILESTONES.md Router groups, Configs 2025-12-14 20:09:06 -06:00
phpstan.neon.dist initial commit 2025-12-14 17:10:01 -06:00
phred initial commit 2025-12-14 17:10:01 -06:00
phred.bat initial commit 2025-12-14 17:10:01 -06:00
README.md Router groups, Configs 2025-12-14 20:09:06 -06:00

Phred

A PHP MVC framework:

  • Intended for projects of all sizes, and solo or team development.
    • The single router call per controller style makes it easy for teamwork without stepping on each others toes.
  • REQUIREMENTS
    • PHP 8.1+
    • Primarily meant for Apache/Nginx webservers, will look into supporting other webservers in the future.
  • PSR-4 autoloading.
  • Installed through Composer (composer create-project getphred/phred)
  • Environment variables (.env) for configuration.
  • Supports two API formats
    • pragmatic REST (default)
    • JSON:API
    • Choose via .env:
      • API_FORMAT=rest (plain JSON responses, RFC7807 error format.)
      • API_FORMAT=jsonapi (JSON:API compliant documents and error objects.)
      • You may also negotiate per request using the Accept header.
  • TESTING environment variables (.env)
    • TEST_RUNNER=codeception
    • TEST_PATH=tests
      • TEST_PATH is relative to both project root and each module root.
  • Dependency Injection
  • Fully Pluggable, but ships with defaults:
    • Pluggability model
      • Core depends on Phred contracts (Phred\Contracts\*) and PSRs
      • Concrete implementations are provided by Service Providers.
      • Swap packages by changing .env and enabling a provider.
    • Driver keys (examples)
      • ORM_DRIVER=pairity|doctrine
      • TEMPLATE_DRIVER=eyrie|twig|plates
      • FLAGS_DRIVER=flagpole|unleash
      • TEST_RUNNER=codeception
    • Primary contracts
      • Template\RendererInterface
      • Orm\EntityManagerInterface (or repositories)
      • Flags\FeatureFlagClientInterface
      • Testing\TestRunnerInterface.
    • Default Plug-ins
      • Feature Flags through getphred/flagpole
      • ORM through getphred/pairity (handles migrations, seeds, and db access)
      • Unit Testing through codeception/codeception
        • Testing is provided as a CLI dev capability only; it is not part of the HTTP request lifecycle.
      • Template Engine through getphred/eyrie
  • Other dependencies:
    • Dependency Injection through php-di/php-di
    • Static Analysis through phpstan/phpstan
    • Code Style Enforcement through friendsofphp/php-cs-fixer
    • Logging through monolog/monolog
    • Config and environment handling through vlucas/phpdotenv
    • HTTP client through guzzlehttp/guzzle
  • CONTROLLERS
    • Invokable controllers (Actions),
      • Single router call per controller,
      • public function __invoke(Request $request) method entry point on controller class,
  • VIEWS
    • Classes for data manipulation/preparation before rendering Templates,
      • $this->render(<template_name>, <data_array>); to render a template.
  • SERVICES
    • for business logic.
  • SERVICE PROVIDERS
    • for dependency injection.
  • MIGRATIONS
    • for database changes.
  • Modular separation, similar to Django apps.
    • Nested Models
    • Nested Controllers
    • Nested Views
    • Nested Services
    • Nested Migrations
    • Nested Service Providers
    • Nested Routes
    • Nested Templates
    • Nested Tests
  • CLI Helper called phred
    • php phred create:command <name> // Creates a CLI command under `console/commands
    • php phred create:module <name> // Creates a module
    • php phred create:<module>:controller // Creates a controller in the specified module
    • php phred create:<module>:model // Creates a model in the specified module
    • php phred create:<module>:migration // Creates a migration in the specified module
    • php phred create:<module>:seed // Creates a seeder in the specified module
    • php phred create:<module>:test // Creates a test in the specified module
    • php phred create:<module>:view / Creates a view in the specified module
    • php phred db:backup // Backup the database
    • php phred db:restore -f <db_backup_file> // Restore the database from the specified backup file
    • php phred migrate [-m <module>] // Migrate entire project or module
    • php phred migration:rollback [-m <module>] // Rollback entire project or module
    • php phred seed
    • php phred seed:rollback
    • php phred test[:<module>] // Test entire project or module
      • Runs tests using the configured test runner (dev only).
      • Requires require-dev dependencies.
    • php phred run [-p <port>]
      • Spawns a local PHP webserver on port 8000 (unless specified otherwise using -p)
  • CLI Helper is extendable through CLI Commands.

Command discovery

  • Core commands (bundled with Phred) are discovered from src/commands.
  • User/project commands are discovered from console/commands in your project root.

Run the CLI:

php phred list

Add your own command by creating a PHP file under console/commands, returning an instance of Phred\Console\Command (or an anonymous class extending it).

(Or by running php phred create:command <name>)

Example:

<?php
use Phred\Console\Command;
use Symfony\Component\Console\Input\InputInterface as Input;
use Symfony\Component\Console\Output\OutputInterface as Output;

return new class extends Command {
    protected string $command = 'hello:world';
    protected string $description = 'Example user command';
    public function handle(Input $in, Output $out): int { $out->writeln('Hello!'); return 0; }
};

Configuration and environment

  • Phred uses vlucas/phpdotenv to load a .env file from your project root (loaded in bootstrap/app.php).
  • Access configuration anywhere via Phred\Support\Config::get(<key>, <default>).
    • Precedence: environment variables > config files > provided default.
    • Keys may be provided in either UPPER_SNAKE (e.g., APP_ENV) or dot.notation (e.g., app.env).
    • Config files live under config/*.php and return arrays; dot keys are addressed as <file>.<path> (e.g., app.timezone).

Common keys

  • APP_ENV (default from config/app.php: local)
  • APP_DEBUG (true/false)
  • APP_TIMEZONE (default UTC)
  • API_FORMAT (rest | jsonapi; default rest)

Examples

use Phred\Support\Config;

$env = Config::get('APP_ENV', 'local');      // reads from env, then config/app.php, else 'local'
$tz  = Config::get('app.timezone', 'UTC');   // reads nested key from config files
$fmt = strtolower(Config::get('API_FORMAT', 'rest'));