jinexus-framework/jinexus-mvc

MVC component from JiNexus Framework

Maintainers

Package info

github.com/jinexus-framework/jinexus-mvc

Type:component

pkg:composer/jinexus-framework/jinexus-mvc

Transparency log

Statistics

Installs: 6

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-07-29 19:30 UTC

This package is auto-updated.

Last update: 2026-07-29 19:46:27 UTC


README

JiNexus MVC is a minimal, component-based MVC kernel for PHP 8.5+. It provides a request–dispatch–render pipeline by wiring together several JiNexus components:

  • Route — URI matching against a named route table
  • Config — merged module configuration
  • Http — request/response abstraction
  • ModuleManager — module loading and config aggregation

The framework is deliberately unopinionated beyond the pipeline shape. Controllers, views, and models are plain PHP objects that implement the provided interfaces.

Requirements

  • PHP ^8.5
  • jinexus-framework/jinexus-config ^1.1
  • jinexus-framework/jinexus-http ^1.1
  • jinexus-framework/jinexus-module-manager ^1.1
  • jinexus-framework/jinexus-route ^1.1

Installation

Install via Composer:

composer require jinexus-framework/jinexus-mvc

Quick start

use JiNexus\Mvc\Application\Factory\ApplicationFactory;

$app = ApplicationFactory::build([
    'modules' => [
        App\Module::class,
    ],
]);

$app->run();

Module configuration

Each module class provides a getConfig(): array method that returns its routes and view configuration. The application factory aggregates all module configs via array_merge_recursive and passes the result to the pipeline:

namespace App;

class Module
{
    public function getConfig(): array
    {
        return [
            'routes' => [
                'home' => [
                    'route'      => '/',
                    'controller' => 'App\Controller\IndexController',
                    'action'     => 'index',
                ],
            ],
            'view_manager' => [
                'template_map' => [
                    'layout/layout' => 'module/Application/view/layout.phtml',
                    'error/404'     => 'module/Application/view/error/404.phtml',
                ],
                'template_path_stack' => ['module/Application/view'],
            ],
        ];
    }
}

Creating a controller

Controllers extend AbstractController and implement action methods suffixed with Action. Each action can return void (no view variables) or a ViewModel:

namespace App\Controller;

use JiNexus\Mvc\Controller\AbstractController;
use JiNexus\Mvc\Model\ViewModel;

class IndexController extends AbstractController
{
    public function indexAction()
    {
        // Reads $this->request, $this->http, $this->view, $this->redirect
    }

    public function jsonAction()
    {
        return new ViewModel(['key' => 'value']);
    }
}

Controller actions have access to:

Property Type Source
$this->view ViewInterface The application's view
$this->http HttpInterface The application's HTTP container
$this->request RequestInterface From $this->http->request
$this->redirect RedirectInterface From the application's route redirect

The view layer

View is a variable bag with PHTML rendering. Use it directly or via the application's $app->view:

$view->set('title', 'Hello');
$view->get('title');                // 'Hello'
$view->has('title');                // true
$view->get('missing', 'fallback');  // 'fallback'
$view->add(['key' => 'val']);       // merge
$view->remove('title');             // delete

$html = $view->render('path/to/template.phtml');

When $app->run() completes, the configured layout template is rendered with all view variables extracted into scope.

The application pipeline

The run() method executes these steps:

  1. View dispatchdispatchView() creates a View bound to the application.
  2. Route match — If no route matches the current URI, 404 headers are sent and the application terminates.
  3. Controller dispatchdispatchController() instantiates the matched controller.
  4. Action dispatchdispatchAction($controller) calls the matched action method.
  5. View renderrenderView() renders the configured layout template.

Accessing pipeline properties

$app->matchRoute;       // array — the matched route, or [] on 404
$app->namespace;        // string — controller FQCN
$app->moduleName;       // string — first namespace segment
$app->controllerName;   // string — last namespace segment
$app->actionName;       // string — the matched action

All pipeline properties are read-only (PHP 8.5 property hooks).

Error handling

PHP errors are converted to ErrorException instances via the AbstractApplication::error() static method, which is registered as the error handler during ApplicationFactory::build().

Package-level failures throw JiNexus\Mvc\MvcException (a subclass of \Exception).

Testing

composer install
composer test            # or: ./vendor/bin/phpunit
composer test:coverage   # text coverage report

phpunit.dist.xml is the committed configuration. Use XDEBUG_MODE=off to silence the local Xdebug notice, and --testdox for readable output:

XDEBUG_MODE=off ./vendor/bin/phpunit --testdox

Extending

Application, View, and factory classes are deliberately empty subclasses of their abstract parents. Keep them that way — the public accessors are implemented with PHP property hooks over backing fields, and declaring a real property would shadow them. For IDE autocompletion, prefer @property PHPDoc tags over real properties.

Contributing

Please see CONDUCT.md for the code of conduct. Contributions should include tests and a CHANGELOG.md entry. See AGENTS.md for detailed build, style, and workflow conventions.

License

BSD-3-Clause. See LICENSE.md.