PHPackages                             frontcontroller/frontcontroller - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. frontcontroller/frontcontroller

ActiveLibrary[Framework](/categories/framework)

frontcontroller/frontcontroller
===============================

Frontcontroller framework

02[1 PRs](https://github.com/linkorb/frontcontroller/pulls)PHP

Since Jan 9Pushed 2y ago1 watchersCompare

[ Source](https://github.com/linkorb/frontcontroller)[ Packagist](https://packagist.org/packages/frontcontroller/frontcontroller)[ RSS](/packages/frontcontroller-frontcontroller/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Introduction
============

[](#introduction)

Frontcontroller is a super light weight website serving application.

It receives all incoming requests, and allows you to route these to various modules.

For each route (url), you can specify a module to handle the request.

Example modules:

- Twig: CMS / Template renderer
- File: serve static files (images, css, js, etc)
- Redirect: respond with different types of redirect headers
- ReverseProxy: Pass requests on to backend servers
- Form: Submit a (contact) form and email the results
- ... etc

It's easy to add new modules that can handle new types of requests

Installation
============

[](#installation)

Install dependencies
--------------------

[](#install-dependencies)

```
composer install

```

Configuration
-------------

[](#configuration)

Copy the provided `.env.dist` file to `.env`, and adjust for your situation.

Please refer to the example `.env.dist` file's comments to see what the configuration options mean.

Creating a website
------------------

[](#creating-a-website)

Websites are all managed in their own directories.

### routes.yml

[](#routesyml)

This `routes.yml` file in the root of your website directory allows you to configure a list of urls, and how you would like to handle them.

An example:

```
frontpage:
    path: /
    defaults:
        _controller: TwigTemplate
        template: "@Website\\frontpage.html.twig"
contact:
    path: /contact
    defaults:
        _controller: TwigTemplate
        template: "@Website\\contact.html.twig"
```

This will enable `/` and `/contact` to work. Both routes will be served using a Twig template.

### templates/\*.html.twig

[](#templateshtmltwig)

You can store your Twig templates ([twig.symfony.com](https://twig.symfony.com)) in the `templates/` directory. By creating routes for these templates you can view them.

### assets (static files)

[](#assets-static-files)

You can store your images, javascript files, css files, etc in any subdirectory (i.e. `assets/`). By creating a route for your assets they can be served. For example:

```
assets:
    path: /assets/{postfix}
    defaults:  { _controller: StaticFile, basedir: assets/ }
    requirements:
        postfix: .*
```

This will allow your assets to be available on `/assets/my.png`. You can now use these assets in your (twig) templates.

You can create multiple routes for static assets, for example if you want to split your css, js and images into their own directories.

### Forms

[](#forms)

You can easily create a route that handles your form submissions, and email them to a preconfigured recipient.

For example:

```
form-submit:
    path: /form-submit
    defaults:
        _controller: Form
        recipient: "joe@example.web"
        subject: "New call-me request from {firstname}"
```

You can now create a simple HTML5 form anywhere on your website and submit them to `/form`. For example:

```
My call-me form:

    Submit

```

### Datasources

[](#datasources)

You can include dynamic content such as blog-posts, pages, products, etc by defining a "Datasource".

A datasource can be any HTTP(s) URL that returns JSON. Often this is an API endpoint of a "headless" CMS (such as [directus](https://getdirectus.com/)), but a datasource can be any API server, as long as it returns JSON data.

Please refer to the example `.env.dist` to see how to configure your datasource. Using the `.env` file you set up the BASEURL and optionally USERNAME and PASSWORD to make HTTP requests too.

Now for every route where you want to use the dynamic data, you define the "data".

In the example below we'll set up a dynamic blog, managed in Directus. In the same way you could dynamically create routes and templates for things like products, team-members, etc etc.

```
blog:
    path: /blog
    defaults:
        _controller: TwigTemplate
        template: "@Website\\blog_index.html.twig"
        data:
            blogs: { path: /tables/blog/rows?order[id]=DESC }
```

You can now use the `blogs` variable (array) in your blog\_index.html.twig template.

For example:

```
My blogs
{% for blog in blogs.data %}
  {{ blogs.headline }}
  {{blogs.summary}}
  Read more...

{% endfor %}
```

Let's create the blog view route:

```
blog_view:
    path: /blog/{blogUri}
    defaults:
        _controller: TwigTemplate
        template: "@Website\\blog_view.html.twig"
        data:
            blog: { path: "/tables/blog/rows?in[uri]={blogUri}", offset: data, mode: first }

```

Note how the `path` contains a variable (blogUri), that we'll use in the `data` definition as part of the `path`.

Also the `offset` is specified. This allows you to only fetch the data you need in case the returned JSON data is wrapped in parent elements you don't really need. For example, directus returns the actual row data wrapped in `meta` and `data` keys. By specifying `offset: data`, the `blog` variable now only contains the real row data.

Normally the datasource returns an array of rows. In case you only need the first one, you simply specify `mode: first`.

In the `blog_view.html.twig` the `blog` array is now available:

```
{{ blog.headline}}
Posted at {{ blog.postedAt}} by {{ blog.author }}
{{ blog.content|markdown|raw }}
```

Note how we're running the `blog.content` through a `markdown` filter, and a `raw` filter.

The `markdown` filter turns markdown content into HTML. The `raw` filter will unescape the HTML tags so they are properly displayed. You can find more filters and their documentation in the [Twig filter documentation](https://twig.symfony.com/doc/2.x/filters/index.html)

Starting server in development mode
-----------------------------------

[](#starting-server-in-development-mode)

```
php -S 0.0.0.0:54321 -t web web/index.php

```

Now open localhost:54321 in your browser.

Troubleshooting
===============

[](#troubleshooting)

No images / scripts / assets using PHP built-in server
------------------------------------------------------

[](#no-images--scripts--assets-using-php-built-in-server)

You need to explicitly add `web/index.php` to your startup command, otherwise the built-in server won't support files with `.` characters in them.

License
-------

[](#license)

MIT. Please refer to the [license file](LICENSE) for details.

Brought to you by the LinkORB Engineering team
----------------------------------------------

[](#brought-to-you-by-the-linkorb-engineering-team)

[![](https://camo.githubusercontent.com/62fb66b034de7ea7fca9fd9776424b5348daa76ef8622caf92c2f7622003e5ef/687474703a2f2f7777772e6c696e6b6f72622e636f6d2f642f6d6574612f74696572312f696d616765732f6c696e6b6f7262656e67696e656572696e672d6c6f676f2e706e67)](https://camo.githubusercontent.com/62fb66b034de7ea7fca9fd9776424b5348daa76ef8622caf92c2f7622003e5ef/687474703a2f2f7777772e6c696e6b6f72622e636f6d2f642f6d6574612f74696572312f696d616765732f6c696e6b6f7262656e67696e656572696e672d6c6f676f2e706e67)
Check out our other projects at [linkorb.com/engineering](http://www.linkorb.com/engineering).

Btw, we're hiring!

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity2

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1db66b320db18b8036ea68211b7d8a39e7c6da97e6fd29f59a50380ebb69d0bb?d=identicon)[joostfaassen](/maintainers/joostfaassen)

---

Top Contributors

[![joostfaassen](https://avatars.githubusercontent.com/u/411113?v=4)](https://github.com/joostfaassen "joostfaassen (28 commits)")[![h-wang](https://avatars.githubusercontent.com/u/3410322?v=4)](https://github.com/h-wang "h-wang (9 commits)")

### Embed Badge

![Health badge](/badges/frontcontroller-frontcontroller/health.svg)

```
[![Health](https://phpackages.com/badges/frontcontroller-frontcontroller/health.svg)](https://phpackages.com/packages/frontcontroller-frontcontroller)
```

###  Alternatives

[laravel/telescope

An elegant debug assistant for the Laravel framework.

5.2k67.8M192](/packages/laravel-telescope)[spiral/roadrunner

RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins

8.4k12.2M84](/packages/spiral-roadrunner)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

708181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
