logo small

Tico PHP MVC Framework: Framework to implement MVC applications in PHP

Recommend this page to a friend!
Download Download
Info Example View files Files Install with Composer Install with Composer Download Download Reputation Support forum Blog Links
Last Updated Ratings Unique User Downloads Download Rankings
2025年10月06日 (Less than 1 hour ago) RSS 2.0 feed Not enough user ratings Total: 166 All time: 8,899 This week: 39Up
Version License PHP version Categories
Description

Author

This package is a framework to implement MVC applications in PHP.

It provides an application class that has a fluent interface with functions to:

- Define model objects
- Define view objects
- Route HTTP requests that match certain URL patterns to handler functions
- Middleware functions to process details of the current HTTP request like user authentication, user sessions, etc..

The framework can handle all requests from a single application script.

Picture of Nikos M.
Name: Nikos M. is available for providing paid consulting. Contact Nikos M. .
Classes: 21 packages by
Country: Greece Greece
Age: 49
All time rank: 8449 in Greece Greece
Week rank: 195 Up2 in Greece Greece Up
Innovation award
Innovation award
Nominee: 8x

Winner: 2x

Example

<?php

define
('ROOT', dirname(__FILE__));
include(
ROOT . '/../tico/Tico.php');

class
MyModel
{
public function
getMsg()
{
return
"Hello";
}
}

tico('http://localhost:8000', ROOT)
->
option('webroot', ROOT)
->
option('views', [tico()->path('/views')])
->
option('normalized_uris', true)
->
option('normalize_uri', function($part) {
$part = str_replace(array('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?'), array('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?'), mb_strtolower($part, 'UTF-8'));
return
$part;
})
->
option('route_params_object', true)
//->set('model', new MyModel()) // simple dependency injection container
->set('model', function() {
return new
MyModel();
})
// container supports lazy factory-like functions
->set('cache', function() {
include
tico()->path('/lib/CacheManager.php');
return (new
CacheManager())
->
option('cache_dur_sec', 2 * 60/*2 minutes*/)
->
option('cache_dir', tico()->path('/cache/data'))
;
})
// container supports lazy factory-like functions
->hook('tico_before_serve_cached', function() {
// a custom hook
tico()->variable('tico_before_serve_cached__content', tico()->variable('tico_before_serve_cached__content')."\n\n<!--cached version-->");
})
;


// if cache enabled and served, exit fast and early
(tico()->serveCache())

or

// else serve request normally, using full framework
(tico()
->
middleware(function($next) {

// eg check if user is authenticated,
// for example check user cookie and set user var appropriately
tico()->set('user', tico()->request()->cookies->get('user', 'guest'));
// start session example (eg native php session)
$session = new HttpSession(/*array(..)*/);
tico()->request()->setSession($session);
$session->start();
if (!
$session->has('count')) $session->set('count', 0);
$next();

})
->
middleware(function($next) {

// if this condition is met, abort current request, eg user is not authenticated
if (('guest' == tico()->get('user')) && ('/hello/foo' == tico()->requestPath()))
//tico()->redirect(tico()->uri('/hello/bar'), 302);
tico()->output(
array(
'title' => 'Hello!', 'msg' => 'guest', 'count'=> 0),
'hello.tpl.php'
);
// else pass along
else
$next();

})
->
on('*', '/', function() {

tico()->output(
// streamed output
function() {
echo
tico()->tpl('index.tpl.php', array('title' => 'Demo Index'));
},
'html'
);

})
->
on(['get', 'post'], '/hello/{:msg}', function($params) {

$session = tico()->request()->getSession();
$session->set('count', $session->get('count')+1);
tico()->output(
array(
'title' => 'Hello!',
'msg' => ('msg:'.$params->get('msg', '&lt;empty&gt;', true)).(',param:'.tico()->requestParam('param', '&lt;empty&gt;')) /*in original case*/,
'count'=> $session->get('count')
),
'hello.tpl.php'
);

})
// utf8 normalized uris
->on(['get', 'post'], '/????/{:msg}', function($params) {

$session = tico()->request()->getSession();
$session->set('count', $session->get('count')+1);
tico()->output(
array(
'title' => '????!',
'msg' => ('msg:'.$params->get('msg', '&lt;empty&gt;', true)).(',param:'.tico()->requestParam('param', '&lt;empty&gt;')) /*in original case*/,
'count'=> $session->get('count')
),
'hello.tpl.php'
);

})
->
onGroup('/foo', function() {

// group routes under common prefix
tico()
// /foo
->on('*', '/', function() {
tico()->output(
array(
'title' => 'Group Route',
'msg' => 'Group Route /foo',
'count'=> 0
),
'hello.tpl.php'
);
})
// /foo/moo
->on('*', '/moo', function() {
tico()->output(
array(
'title' => 'Group Route',
'msg' => 'Group Route /foo/moo',
'count'=> 0
),
'hello.tpl.php'
);
})
// /foo/koo
->onGroup('/koo', function() {
tico()
// /foo/koo
->on('*', '/', function() {
tico()->output(
array(
'title' => 'Group Route',
'msg' => 'Group Route /foo/koo',
'count'=> 0
),
'hello.tpl.php'
);
})
// /foo/koo/soo
->on('*', '/soo', function() {
tico()->output(
array(
'title' => 'Group Route',
'msg' => 'Group Route /foo/koo/soo',
'count'=> 0
),
'hello.tpl.php'
);
})
;
})
;

})
->
on('*', '/json/api', function() {

tico()->output(array(
'param1' => '123',
'param2' => '456',
'param3' => '789'
), 'json');

})
->
on('*', '/download', function() {

tico()->output(
tico()->path('/file.txt'),
'file'
);

})
->
on('*', '/redirect', function() {

tico()->redirect(tico()->uri('/'), 302);

})
->
on(false, function() {

tico()->output(
array(),
'404.tpl.php',
array(
'StatusCode' => 404)
);

})
->
middleware(function($next) {

// post process, eg create cache files from response
if ((200 == tico()->response()->getStatusCode()) && 'text/html'==tico()->response()->headers->get('Content-Type') && !tico()->response()->getFile() && !tico()->response()->getCallback())
{
tico()->response()->setContent(tico()->response()->getContent() . '<!-- post processed -->');
}

},
'after')
->
serve())
;

exit;


Details

tico

Mini, super-simple and versatile MVC Web Framework for PHP (v.1.22.0)

Uses:

  1. Importer class &amp; asset dependency loader
  2. Dromeo versatile pattern router
  3. InTpl simple php templates w/ inheritance
  4. HttpFoundation, adapted from Symfony's HttpFoundation component (v.7.3.1 / 2025)

Hooks in order of execution:

serve normal response

  1. `tico_before_serve`
  2. `tico_before_middleware_before`
  3. `tico_after_middleware_before`
  4. `tico_before_route`
  5. `tico_after_route`
  6. `tico_before_middleware_after`
  7. `tico_after_middleware_after`
  8. `tico_prepared_response`
  9. `tico_cache_response`
  10. `tico_send_response`
  11. `tico_after_serve`

serve cached response

  1. `tico_serve_cache`
  2. `tico_before_serve_cached`
  3. `tico_after_serve_cached`

various hooks run in-between when data are set or changed:

  1. `tico_request`, set request object
  2. `tico_response`, set response object
  3. `tico_set_callback`, change streamed output via callback
  4. `tico_set_content`, change output content
  5. `tico_set_file`, change/remove output file
  6. `tico_redirect`, change/remove redirect url
  7. `tico_autoload`, change/remove autoload classes
  8. `tico_enqueue`, change/remove enqueued asset

demo (see /demo/index.php)

define('ROOT', dirname(__FILE__));
include(ROOT . '/../tico/Tico.php');
class MyModel
{
 public function getMsg()
 {
 return "Hello";
 }
}
tico('http://localhost:8000', ROOT)
 // some options
 ->option('webroot', ROOT) // default
 ->option('views', [tico()->path('/views')])
 ->option('normalized_uris', true) // default
 ->option('normalize_uri', function($part) {
 return str_replace(array('?','?','?','?','?','?','?','?','?','?','?','?'), array('?','?','?','?','?','?','?','?','?','?','?','?'), mb_strtolower($part, 'UTF-8'));
 })
 /*->option('tpl_render', function($tpl, $data, $viewsFolders) {
 // custom template renderer
 return MyFancyTpl::render($tpl, $data);
 })*/
 //->set('model', new MyModel()) // simple dependency injection container
 ->set('model', function() {
 return new MyModel();
 }) // container supports lazy factory-like functions
 ->set('cache', function() {
 // any custom caching solution can be used that has get/set methods, here a simple CacheManager
 include tico()->path('/cache/CacheManager.php');
 return (new CacheManager())
 ->option('cache_dur_sec', 10 60/10 minutes*/)
 ->option('cache_dir', tico()->path('/cache/data'))
 ;
 }) // container supports lazy factory-like functions
 ->hook('tico_before_serve_cached', function() {
 // a custom hook
 tico()->variable('tico_before_serve_cached__content', tico()->variable('tico_before_serve_cached__content')."\n\n<!--cached version-->");
 })
;
// if cache enabled and served, exit fast and early
(tico()->serveCache())
or
// else serve request normally, using full framework
(tico()
// middleware functionality
->middleware(function($next) {
 // eg check if user is authenticated,
 // for example check user cookie and set user var appropriately
 tico()->set('user', tico()->request()->cookies->get('user', 'guest'));
 // start session example (eg native php session)
 $session = new HttpSession(/array(..)/);
 tico()->request()->setSession($session);
 $session->start();
 if (!$session->has('count')) $session->set('count', 0);
 $next();
})
->middleware(function($next) {
 // if this condition is met, abort current request, eg user is not authenticated
 if (('guest'==tico()->get('user')) && ('/hello/foo'==tico()->requestPath()))
 //tico()->redirect(tico()->uri('/hello/bar'), 302);
 tico()->output(
 array('title' => 'Hello!', 'msg' => 'guest'),
 'hello.tpl.php'
 );
 // else pass along
 else
 $next();
})
// can handle other ports from same script, as long as handling is directed to this file
// on :4040 port, '*' means on any port
->onPort(4040, function() {
 tico()
 ->on('*', '/', function() {
 tico()->output(
 array('title' => 'Demo Port Index'),
 '4040/index.tpl.php'
 );
 })
 ->on(false, function() {
 tico()->output(
 array(),
 '4040/404.tpl.php',
 array('StatusCode' => 404)
 );
 })
 ;
})
// can handle subdomains from same script, as long as subdomain handling is directed to this file
// on "foo." subdomain, '*' means on any subdomain
->onSubdomain('foo', function() {
 tico()
 ->on('*', '/', function() {
 tico()->output(
 array('title' => 'Demo Subdomain Index'),
 'foo/index.tpl.php'
 );
 })
 ->on(false, function() {
 tico()->output(
 array(),
 'foo/404.tpl.php',
 array('StatusCode' => 404)
 );
 })
 ;
})
// on main domain / port
->on('*', '/', function() {
 tico()->output(
 array('title' => 'Demo Index'),
 'index.tpl.php'
 );
})
->on(['get', 'post'], '/hello/{:msg}', function($params) {
 $session = tico()->request()->getSession();
 $session->set('count', $session->get('count')+1);
 tico()->output(
 array(
 'title' => 'Hello!',
 'msg' => $params[':']['msg'], // original msg
 'count'=> $session->get('count')
 ),
 'hello.tpl.php'
 );
})
// unicode normalized uris
->on(['get', 'post'], '/????/{:msg}', function($params) {
 $session = tico()->request()->getSession();
 $session->set('count', $session->get('count')+1);
 tico()->output(
 array(
 'title' => '????!',
 'msg' => $params[':']['msg'], // original msg
 'count'=> $session->get('count')
 ),
 'hello.tpl.php'
 );
})
// group routes under common prefix
->onGroup('/foo', function() {
 tico()
 // /foo
 ->on('*', '/', function() {
 tico()->output(
 array(
 'title' => 'Group Route',
 'msg' => 'Group Route /foo',
 'count'=> 0
 ),
 'hello.tpl.php'
 );
 })
 // /foo/moo
 ->on('*', '/moo', function() {
 tico()->output(
 array(
 'title' => 'Group Route',
 'msg' => 'Group Route /foo/moo',
 'count'=> 0
 ),
 'hello.tpl.php'
 );
 })
 // /foo/koo
 ->onGroup('/koo', function() {
 tico()
 // /foo/koo
 ->on('*', '/', function() {
 tico()->output(
 array(
 'title' => 'Group Route',
 'msg' => 'Group Route /foo/koo',
 'count'=> 0
 ),
 'hello.tpl.php'
 );
 })
 // /foo/koo/soo
 ->on('*', '/soo', function() {
 tico()->output(
 array(
 'title' => 'Group Route',
 'msg' => 'Group Route /foo/koo/soo',
 'count'=> 0
 ),
 'hello.tpl.php'
 );
 })
 ;
 })
 ;
})
->on('*', '/json/api', function() {
 tico()->output(array(
 'param1' => '123',
 'param2' => '456',
 'param3' => '789'
 ), 'json');
})
->on('*', '/download', function() {
 tico()->output(
 tico()->path('/file.txt'),
 'file'
 );
})
->on('*', '/redirect', function() {
 tico()->redirect(tico()->uri('/'), 302);
})
->on(false, function() {
 tico()->output(
 array(),
 '404.tpl.php',
 array('StatusCode' => 404)
 );
})
// middlewares are same for main domain and all subdomains and all ports
->middleware(function($next) {
 // post process, eg create cache files from response
 if ((200 == tico()->response()->getStatusCode()) && 'text/html'==tico()->response()->headers->get('Content-Type') && !tico()->response()->getFile() && !tico()->response()->getCallback())
 {
 tico()->response()->setContent(tico()->response()->getContent().'<!-- post processed -->');
 }
}, 'after')
->serve())
;

see also:

  • ModelView a simple, fast, powerful and flexible MVVM framework for JavaScript
  • tico a tiny, super-simple MVC framework for PHP
  • LoginManager a simple, barebones agnostic login manager for PHP, JavaScript, Python
  • SimpleCaptcha a simple, image-based, mathematical captcha with increasing levels of difficulty for PHP, JavaScript, Python
  • Dromeo a flexible, and powerful agnostic router for PHP, JavaScript, Python
  • PublishSubscribe a simple and flexible publish-subscribe pattern implementation for PHP, JavaScript, Python
  • Localizer a simple and versatile localization class (l10n) for PHP, JavaScript, Python
  • Importer simple class &amp; dependency manager and loader for PHP, JavaScript, Python
  • EazyHttp, easy, simple and fast HTTP requests for PHP, JavaScript, Python
  • Contemplate a fast and versatile isomorphic template engine for PHP, JavaScript, Python
  • HtmlWidget html widgets, made as simple as possible, both client and server, both desktop and mobile, can be used as (template) plugins and/or standalone for PHP, JavaScript, Python (can be used as plugins for Contemplate)
  • Paginator simple and flexible pagination controls generator for PHP, JavaScript, Python
  • Formal a simple and versatile (Form) Data validation framework based on Rules for PHP, JavaScript, Python
  • Dialect a cross-vendor &amp; cross-platform SQL Query Builder, based on GrammarTemplate, for PHP, JavaScript, Python
  • DialectORM an Object-Relational-Mapper (ORM) and Object-Document-Mapper (ODM), based on Dialect, for PHP, JavaScript, Python
  • Unicache a simple and flexible agnostic caching framework, supporting various platforms, for PHP, JavaScript, Python
  • Xpresion a simple and flexible eXpression parser engine (with custom functions and variables support), based on GrammarTemplate, for PHP, JavaScript, Python
  • Regex Analyzer/Composer Regular Expression Analyzer and Composer for PHP, JavaScript, Python

Files folder image Files (26)
File Role Description
Files folder imagedemo (3 files, 2 directories)
Files folder imagetest (3 files, 2 directories)
Files folder imagetico (5 files)
Accessible without login Plain text file README.md Doc. Documentation

Files folder image Files (26) / demo
File Role Description
Files folder imagelib (1 file)
Files folder imageviews (4 files, 1 directory)
Accessible without login Plain text file file.txt Data Auxiliary data
Accessible without login Plain text file index.php Example Example script
Accessible without login Plain text file server.php Aux. Auxiliary script

Files folder image Files (26) / demo / lib
File Role Description
Plain text file CacheManager.php Class Class source

Files folder image Files (26) / demo / views
File Role Description
Files folder imagelayout (1 file)
Accessible without login Plain text file 404.tpl.php Example Example script
Accessible without login Plain text file content.tpl.php Example Example script
Accessible without login Plain text file hello.tpl.php Example Example script
Accessible without login Plain text file index.tpl.php Example Example script

Files folder image Files (26) / demo / views / layout
File Role Description
Accessible without login Plain text file base.tpl.php Example Example script

Files folder image Files (26) / test
File Role Description
Files folder imagesubfolder (2 files, 1 directory)
Files folder imageviews (2 files, 1 directory)
Accessible without login Plain text file .htaccess Data Auxiliary data
Accessible without login Plain text file index.php Example Example script
Accessible without login Plain text file server.php Aux. Configuration script

Files folder image Files (26) / test / subfolder
File Role Description
Files folder imageviews (2 files, 1 directory)
Accessible without login Plain text file .htaccess Data Auxiliary data
Accessible without login Plain text file index.php Example Example script

Files folder image Files (26) / test / subfolder / views
File Role Description
Files folder imagelayout (1 file)
Accessible without login Plain text file 404.tpl.php Example Example script
Accessible without login Plain text file hello.tpl.php Example Example script

Files folder image Files (26) / test / subfolder / views / layout
File Role Description
Accessible without login Plain text file base.tpl.php Example Example script

Files folder image Files (26) / test / views
File Role Description
Files folder imagelayout (1 file)
Accessible without login Plain text file 404.tpl.php Example Example script
Accessible without login Plain text file hello.tpl.php Example Example script

Files folder image Files (26) / test / views / layout
File Role Description
Accessible without login Plain text file base.tpl.php Example Example script

Files folder image Files (26) / tico
File Role Description
Plain text file Dromeo.php Class Class source
Plain text file HttpFoundation.php Class Class source
Plain text file Importer.php Class Class source
Plain text file InTpl.php Class Class source
Plain text file Tico.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Version Control Unique User Downloads Download Rankings
100%
Total: 166
This week: 0
All time: 8,899
This week: 39 Up
About us About us Advertise on this site Advertise on this site Site map Site map Newsletter Newsletter Statistics Statistics Site tips Site tips Privacy policy Privacy policy Contact Contact

AltStyle によって変換されたページ (->オリジナル) /