Version 3.0.0+uhi67 -- 2026-02-05
A simple web-application framework implementing model-view-controller (MVC) architectural pattern.
- simple html/php based views with rendering hierarchy
- PDO-based database connection with array-based query builder (only MySQL is currently implemented)
- easy-to-use Model classes
- simple URL-path to Controller/method translation with automatic parameter passing
- database migration support
- user login via SAML (Using this feature needs
composer require "simplesamlphp/simplesamlphp:^2.2")
UMVC supports modules, see configuration/components.
The framework supports functional testing with its framework plugin. Globally installed codeception must be compatible with required (currently v3.1.2)
UMVC supports CLI. You may create your own commands. The built-in commands are:
- migrate
- cache
- create
Run commands as php app $command/$action $parameters.
Run php app to get the list of available commands, including the built-in and the application-defined ones.
The framework can be included into your project with composer. Run composer require uhi67/umvc:dev-master.
New, empty project can be created using composer create-project --prefer-dist uhi67/umvc-app name. This will deliver you a new empty application using UMVC framework into the named directory. Choose any name you prefer.
Warning: This part is under construction. Learn more about the mentioned classes in the docblock of the class definition.
- Create
composer.jsonof your application, and includeuh67/umvc, e.gcomposer init --name myname/myapp --require uhi67/umvc:*. - Run
composer update. - Copy
vendor/uh67/umvc/appto your application's root. This is the launcher of the CLI commands. - Copy
vendor/uh67/umvc/www/index.phpand.htaccessto your application's www directory. This is the router of the web interface. - Create your application's config in the
config/config.phpfile, see template invendor/uh67/umvc/config/config-template.php. - Create a
runtimedirectory writable by the webserver to place temporary files. - Create the
www/assetsdirectory writable by the webserver to place cached asset files of various components.
- Create your controllers in the
controllersdir, using\app\controllersnamespace, and derive them fromuhi67\umvc\Controller. - Create the views in the
viewsdir, in simple PHTML format, and organize them according toviews/controller/action.phpstructure. - Create your models in the
modelsdirectory. Database models are\uhi67\umvc\Model, database-less models are\uhi67\umvc\BaseModel.
- Migrations are for versioning and recording database changes in source code. Place migration steps into
migrationsdirectory. - Layout is a special view to embed all other views within. Place layouts in
views/layoutsdirectory. Views can call other partial views. - You can define CLI commands in
commandsdirectory, deriving from\uhi67\umvc\Commandclass. There are some built-in command in the framework.php appcommand lists all available commands, both built-in and custom ones. - A simple file-based localization support is built-in. Place your translations into
messges/la.phpfiles where "la" is the language you want to translate to.
All components,most of UMVC classes, including the main App class itself, is a \uhi67\umvc\Component.
Component implements property features: magic getter and setter uses getProperty and setProperty methods.
Component is configurable: constructor accepts a configuration array containing values for public properties.
MySqlConnection-- to connect to database. Includes SQL query builder. Currently the only implementation ofConnection.FileCache-- the only implementation ofCacheInterface.SamlAuth-- the only implementation forAuthManager.L10n-- simple localization, default auto-included, translates UMVC messages only.L10nFile-- the file-based localization to translate messages of your application.
Form-- a widget with built-in view to display and process HTML forms using your Models.Grid(widget, but the built-in view is still missing) -- to display paginated, filtered lists of Models.Query-- Represents a parametrized and flexible SQL query in php structure. SQL command can be built from it.Request-- Represents the HTTP request, can be used to fetch GET and POST parameters.Session-- Represents the current PHP session, can be used to get and set variables.
The single entry script for the web application is the www/index.php.
Respectively, the single entry script for the CLI application is the app file.
Both of them must be copied into your application directory from the vendor/uhi67/umvc/ directory.
The www/.htaccess rules redirect all not-found requests to the www/index.php.
However, static assets are served directly from the www directory. Learn more about serving library assets later.
The index.php initializes the autoloader, load the main configuration, creates the main object
(class defined in the configuration, usually uhi67/umvc/App or its descendant).
The main configuration follows the rules of the configurable Component.
All URL formed as https://myapp/acontroller/anaction is processed the following way:
uhi67/umvc/App parses the request, computes the actual controller class (derived from uhi67/umvc/Controller) to use,
creates the controller and runs the requested action method. As in the example above, acontroller refers to your controller
class in your controllers directory as AcontrollerController, and anaction refers to the action method (as actionAnaction).
If the action name is missing from the URL, the actionDefault will be run. If the controller name is missing as well,
the configured mainController will be used. It is also possible to create a URL with an action name of the
default controller without specifying the controller name - the only restriction you cannot have a controller with the same name as this action.
Al CLI command formed as php app acontroller/anaction is processed the following way:
uhi67/umvc/App parses the request, computes the actual controller class (derived from uhi67/umvc/Command) to use,
creates the controller and runs the requested action method. As in the example above, acontroller refers to your controller
class in your commands directory as AcontrollerController, and anaction refers to the action method (as actionAnaction).
Built-in commands can be run the same way. A command with the same name in our application overrides the built-in command.
The parts of the current URL request can be accessed as:
- path: the path portion passed to the controller (controller name already shifted out)
- query: the query part of the original request, as an associative array
To create a new URL using controller and action names, and optioanl qurey parameters, use one of the following:
- $this->app->createUrl(['controller/action', 'key'=>'queryvalue', ..., '#'=>'fragment']) -- all parts are optional
- return $this->app->redirect([...]) -- to terminate the action with a redirection
In your view files, you can refer your static assets located under www directory in static way, e.g <link href="/assets/css/app.css" rel="stylesheet">.
On the contrary, if you want to refer to an asset file located somewhere in the composer-created vendor library, you can use them this way:
<script src="<?= $this->linkAssetFile('npm-asset/bootstrap/dist', 'js/bootstrap.bundle.min.js') ?>"></script>
The linkAssetFile function copies all the files from the directory in the first argument into the asset
cache directory under the www , and creates a valid URL to the file int the second argument.
Note: The first argument identifias an asset package. Only the first call for any package copies the files.
All subsequent calls to the same package generates only the link for the file.
The asset cache is emptied by the composer install command.
The asset cache is always www/asset/cache and is not configurable.
- Logging
- Basic structure to update a Model using Form
- Grid pagination and filtering
- Model validation
- Helpers (Classes with static methods only)
...
This repository contains a built-in test application for internal codeception unit tests.
The only purpose of the test app in the tests directory is to be able to run unit tests, and not a sample application to start with.
git clonecomposer update- Create
tests/_data/test-config.phpbased on the template - Create the
umvc-testdatabase according to the database settings intests/_data/test-config.php - Run
php vendor/bin/codecept run unitfor unit tests
More unit tests are coming...
A built-in dockerized testing environment can be used to test with different php and database versions.
Steps:
- configure the needed database version in
tests/docker-compose.yml(make clones of this template file) - configure the php version in
tests/docker/Dockerfile(extension installation steps may change) - configure the used ports and base-url in
tests/.env - build the stack using
docker compose up --build -d(in thetestsdir) - your php container should now be 'umvc-php-1'
- run unit tests with
docker exec -it umvc-php-1 php vendor/bin/codecept run unit
- added MailerPhp component
- Form can be disabled
- cache control
- added ArrayHelper::updateSet()
- added SimpleSamlAuth component
- added Model::friendlyErrors
- added BaseModel::unsetErrors()
- added AppHelper::renderException()
- add BaseController
- add App::login()
- AuthManager::login() with attributes and creation
- AuthManager::actionLogin() and logout() parameters
- migrate/update command with path and namespace
- Controller action exit status
- add Controller::$classPath, $actionPath
- Model::validateUnique() for multiple fields
- BaseModel::addError() with multiple fields
- add Column::$format property (raw or not)
- add FileCache::$permission property
- using php 8.2 types, and PSR12 rules
- jsonErrorResponse schema
- fix Query bind
- add path argument to migrate/up
- add filterHint property to Column (used in Grid widget)
- fix baseUrl (primary source is APP_BASEURL env. var.)
- Model::getOne() now returns null if null value is specified as primary key.
- fix Query::column
- fix AppTestHelper
- jsonResponse parameter name changed
- PSR12
- urlPath, baseUrl fixes
- debug traps removed
- Install::crearDir() now deletes also .gitkeep and .gitignore files
- requires php 8.2
- fix baseUrl usage
- Query::filterInReferredModels() added
- Empty caches: skip .gitignore files
- UMVC guide and refer umvc app
- php 8 compatibility fixes
- Other bugfixes
- SQL Builder: use tablename as default alias
- migrate/wait command added
- postponed connection of Connection
- localized render
- Migration SQL transaction issues
- MySQL 8.0 compatibility, keeping 5.7 compatibility
- App: view path fixed
- CLI config check
- AppHelper::waitFor()
- Unit test fix
- A simple dockerized test application with testing guide is included
- Docker: waiting for database container initialization (simple approach)
- First steps documentation added
- twig/twig < 2.15.3 vulnerability fix (composer.lock)
- AuthManager::actionLogin() added to fix default login return issue
- bugfixes, phpdoc fixes
- linkButton signature has changed
- Connection::connect is back
- Connection information methods (getTables(), etc)
- MysqlConnection dropXXX methods
- migrate/reset command
- unit tests, test app (draft)
- showException previous message fixed
- Model primary key check
- SamlAuth: update user record only at login
- Version file creation removed
- Asset registry improvements (Controller::registerAssets(), etc)
- Html::img() added
- Session, Request, FileUpload classes
- localization (App::l(), App::$locale, L10n, L10nFile, etc)
- App: default layout parameter
- render bugfixes
- SamlAuth::get() fixed
- App::asset() calls must be replaced by App::linkAssetFile() calls (using same arguments)