Online demo (username : p ; password : (leave empty))
Download version 0.30 (uses GET() instead of render())
Version 0.25 (uses XML instead of JSON)
Version 0.15 (uses a cookie instead of $_SESSION)
Version 0.12 (uses sessions ; bilingual : french and english)
Version 0.6 (english only)
Front Controller (FC) is a collection of PHP scripts meant to create portals.
It allows you to create many pages, protected by login and with database access.
It is 554 lines of PHP, HTML and CSS code across 15 files.
It has no JavaScript code.
The application starts with app.php
(the single controller).
app.php
first registers an autoload (so no need for includes anywhere)
To find a view, app.php
loads the view class by prepending 'Vue' to it.
So URL /app.php/En/Bonjour/
loads class VueBonjour
from the app/vue/VueBonjour.php
file.
Supports multiple languages (and can easily support more).
All URLs are created at a central place. (See URL::FullURL()
below). The current language is added to all URLs.
Does not use sessions : There is no "logout delay".
Uses only one cookie : Allows to be connected as long as the browser remembers the cookie.
That cookie is saved in the database and will only change at user request (For example, if the user wishes to log out on other devices).
When the user logs out, the URL is unchanged (so when logging back in, the user will be where he was before logging out).
In fact, the login page does not have its own URL. Instead, a 401 error containing the login page is returned if logging in is required by the view.
Resubmission : If the user was filling a form and was logged out when submitting it, the login page allows him to resend the form data while logging back in.
It is possible to decide which views need login and which don't. (See authenticate()
below).
FC requires a MySQL database to save users.
app/
and style/
folders and the app.php
file to where you want the application to be installed.
app.php
script to something else ('index.php
' for example).
app/
folder by either moving it outside of the document root (and modifying app.php
to point to its new location) or by adding this to an app/.htaccess
file :
Require all deniedor this to your
<VirtualHost>
block :
<DirectoryMatch "/app/"> Require all denied </DirectoryMatch>
app/model/Mdl.php
script.
admin
' with an empty password (do not forget to change it).
Look at the VueUsers.php
view and the MdlUser.php
model for an example.
Creating a new page is simple.
First create a class named VueBonjour
and save it in app/vue/VueBonjour.php
.
<?php class VueBonjour extends Vue { protected function GET() { $this->renderTitle('Bonjour'); ?> <p>Bienvenue. <?php } protected function GET_Coucou() { $this->renderTitle('Coucou'); ?> <p>Hello. <?php } protected function GET_Coucou_Yay() { $this->renderTitle('Yay'); ?> <p>Yay. <?php } } ?>
The main page will then be accessible at the /app.php/En/Bonjour/
URL.
The sub-page will then be accessible at the /app.php/En/Bonjour/Coucou/
URL.
The sub-sub-page will then be accessible at the /app.php/En/Bonjour/Coucou/Yay/
URL.
Every view inherits from the abstract Vue
class.
Vue.php
also provides a renderTitle($title)
function to render the page title and optionally the navigation menu at the top.
To add the page to the navigation menu, edit the $pages
array in the app/vue/Vue.php
file.
Look inside Vue.php
for method signatures. (all the following functions are protected
)
You may implement these methods in your views.
authenticate()
Allows a page to require login.
Return true to allow and false to require a login.
Defaults to AUTH::IsLoggedIn();
authorize($post)
Allows or denies access to a page.
Return true to allow and false to deny.
$post
tells you if the request was a POST request.
Defaults to true
When creating a new view, you may want to access the database.
Do so using a model.
In the app/model/
folder, model classes inherit from the abstract Mdl
class.
Example model :
<?php class MdlBonjour extends Mdl { function getAllBonjours($id = 0) { $sth = $this->pdo()->prepare('SELECT name FROM bonjour WHERE id = :id'); $sth->execute(array('id' => $id)); return $sth->fetchAll(); } } ?>
Mdl.php
provides a pdo()
method which gives you access to the PDO
object.
It is recommended to create one model per database table.
LANG
PAGE
Edit the app.php
file :
define('LANG', $lang ?: 'En');
Edit the app.php
file :
define('PAGE', $page ?: 'Home');
Edit the app/model/Mdl.php
file :
$pdo = new PDO('mysql:dbname=fc;host=localhost;charset=utf8mb4', 'fc', '1qaz2wsx');
Edit the app/vue/Vue.php
file :
private $pages = array( array('PageOne', 'Title of page one'), array('PageTwo', 'Title of page two'), array(array('Bonjour', 'SubPage'), 'Title of SubPage of Bonjour') );
AUTH::GetUser()
Gets the logged in user.
Returns keys id
, name
, fullname
.
AUTH::IsLoggedIn()
Tells if the user is logged in.
AUTH::IsAdmin()
Tells if the user is an admin.
URL::FullURL()
Returns a root relative URL.
URL::FullURL('Bonjour', 123, array('s' => 456))
returns /app.php/En/Bonjour/123/?s=456
URL::FullURLHTML()
Same as URL::FullURL()
but for an HTML context :
<a href="<?= URL::FullURLHTML('Bonjour') ?>">Bonjour</a>
URL::DomainURL()
Returns a full URL (with host name).
URL::DomainURL('Bonjour')
returns http://fc.philippe97.ca/app.php/En/Bonjour/
URL::DomainURLHTML()
Same as URL::DomainURL()
but for an HTML context.
URL::Relative($base, $url)
Resolves a relative URL to a base URL.
$base
is the full base URL (http://...
).
$url
is the relative URL (http://...
or //...
or /...
or ...
).
URL::RelativeHTML($base, $url)
Same as URL::Relative()
but for an HTML context.
URL::AppURL()
Returns a URL relative to the folder containing app.php
.
URL::AppURL('Bonjour')
returns /Bonjour
if the app.php
script is at the root.
URL::AppURLHTML()
Same as URL::AppURL()
but for an HTML context :
<link href="<?= URL::AppURLHTML('style', 'sheet.css') ?>" rel=stylesheet />
HTTP::Reload()
Reloads the current URL.
Useful in POST*()
to change the POST request into a GET.
(if not called, the user will be prompted to resubmit if the reload button is clicked)
HTTP::ReloadURL()
Redirects to another URL.
Accepts the same arguments as URL::FullURL()
Example : HTTP::ReloadURL('Bonjour', 456)
HTTP::Resubmit()
Resubmits the current URL (with 307 code).
Tells the browser to resend the POST request.
HTTP::ResubmitURL()
Resubmits to another URL.
Accepts the same arguments as URL::FullURL()
Example : HTTP::ResubmitURL('Bonjour', 456)
STR::text($key)
Returns a translated string.
Example : STR::text('Welcome')
STR::html($key)
Same as STR::text($key)
but for an HTML context.
Example : <span><?= STR::html('Welcome') ?><span>
Edit the app/xml/Traduction.xml
file and add a new element.
<Es> ... </Es>
You may copy the element of another language.
Sometimes, you may want to make a page accessible to all without having to log in.
To do that, add this to your view class :
protected function authenticate() { return true; }
app.php
from the URLTo remove app.php
from the URL, add one of these two lines to your <VirtualHost>
block :
RewriteEngine On # At the root folder : RewriteRule ^/((En|Fr)(/.*)?)?$ /app.php/$1 # In a subfolder : RewriteRule ^/(subfolder)/((En|Fr)(/.*)?)?$ /$1/app.php/$2
Or this to your .htaccess
file :
RewriteEngine On RewriteRule ^((En|Fr)(/.*)?)?$ app.php/$1
You may add more languages in the rule.