Skip to content

Commit 2feadec

Browse files
author
Ahmad Hegazy
committed
first commit
0 parents  commit 2feadec

24 files changed

+493
-0
lines changed

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# PHP-MVC SKELETON
2+
A PHP OOP web application skeleton that uses MVC architectural pattern to create a basic application that contains login and multi language systems and can be used in any web project.
3+
4+
- It was created to get rid of the trouble of creating a MVC script from scratch
5+
6+
## Description
7+
Basic php skeleton of an MVC (model-view-controller) web application that you can use to build your application upon it or to understand the MVC pattern.
8+
9+
## Features
10+
1- MVC based application
11+
2- MYSQL database connection
12+
3- multi language
13+
4- login system
14+
4- session store and recovery
15+
16+
## How it works
17+
It's a normal MVC application so it consists of models/views/controllers
18+
1- First it runs the initiation script [init.php](app/init.php)
19+
- The initiation script loads main scripts and confinguration files.
20+
2- Then a new app instance is created and the url is parsed in the [App.php](app/core/App.php) class
21+
3- The requested language is set and the requested controller is loaded ex: [home.php](app/controllers/home.php) controller.
22+
4- A controller class instance is created and the requested method called
23+
5- The method calls the model method and in the model loading method we check for login [Controller model](core/Controller.php)
24+
- If the user is loggedin it'll get the requested model, else it'll redirect to login
25+
6- The controller method then calls the view method and in the view loading method we load the language files and the page layout. [Controller view](core/Controller.php)
26+
27+
## Directory structure
28+
1- [app](app): Application backend
29+
- [config](app/config): configuration files
30+
- [core](app/core): core scripts called in app initiation
31+
- [Helper](app/Helper): helper function such as common used and database functions
32+
- [languages](app/languages): languages contain directories with language code
33+
- [controllers](app/controllers): application controllers
34+
- [models](app/models): application models
35+
- [views](app/views): application views
36+
- [init.php](app/init.php): initiation script that includes necessary scripts.
37+
- [.htaccess](app/.htaccess): htaccess file to prevent entering this area for users
38+
39+
2- [public](public)
40+
- [index.php](public/index.php): creates an app instance.
41+
- [.htaccess](public/.htaccess): htaccess to control the url writing
42+
- [css](public/css): contains css style files.
43+
- [js](public/js): contains javascript files.
44+
45+
## How to use it
46+
- Just clone the repo and start building upon the provided skeleton
47+
48+
49+
## Finally
50+
Hope it'll be beneficial i'll be pleased to see contribution and error fixes in this repo
51+
if you have any question or request contact me: Ahmad Hegazy <ahegazipro@gmail.com>

app/.htaccess

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Options -Indexes

app/Helper/Common.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
/*
4+
* class contains common functions used allover the script
5+
*/
6+
class Common {
7+
8+
9+
}

app/Helper/Database.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* class contains database management functions used all over the script
5+
*/
6+
class Database extends Common {
7+
8+
protected $db;
9+
function __construct(){
10+
$this->openDatabaseConnection();
11+
}
12+
13+
function __destruct() {
14+
$this->closeDatabaseConnection();
15+
}
16+
17+
private function openDatabaseConnection()
18+
{
19+
$this->db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
20+
if ($this->db->connect_errno) {
21+
echo "Failed to connect to MySQL: " . $this->db->connect_error;
22+
die();
23+
}
24+
$this->db->set_charset(DB_CHARSET);
25+
}
26+
27+
private function closeDatabaseConnection()
28+
{
29+
$this->db->close();
30+
}
31+
32+
}

app/config/config.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* Configuration
4+
*
5+
* For more info about constants please @see http://php.net/manual/en/function.define.php
6+
*/
7+
/**
8+
* Configuration for: Error reporting
9+
* Useful to show every little problem during development, but only show hard errors in production
10+
*/
11+
define('ENVIRONMENT', 'development');
12+
if (ENVIRONMENT == 'development' || ENVIRONMENT == 'dev') {
13+
error_reporting(E_ALL);
14+
ini_set("display_errors", 1);
15+
}
16+
/**
17+
* Configuration for: URL
18+
* Here we auto-detect your applications URL and the potential sub-folder. Works perfectly on most servers and in local
19+
* development environments (like WAMP, MAMP, etc.). Don't touch this unless you know what you do.
20+
*
21+
* URL_PUBLIC_FOLDER:
22+
* The folder that is visible to public, users will only have access to that folder so nobody can have a look into
23+
* "/application" or other folder inside your application or call any other .php file than index.php inside "/public".
24+
*
25+
* URL_PROTOCOL:
26+
* The protocol. Don't change unless you know exactly what you do. This defines the protocol part of the URL, in older
27+
* versions of MINI it was 'http://' for normal HTTP and 'https://' if you have a HTTPS site for sure. Now the
28+
* protocol-independent '//' is used, which auto-recognized the protocol.
29+
*
30+
* URL_DOMAIN:
31+
* The domain. Don't change unless you know exactly what you do.
32+
*
33+
* URL_SUB_FOLDER:
34+
* The sub-folder. Leave it like it is, even if you don't use a sub-folder (then this will be just "/").
35+
*
36+
* URL:
37+
* The final, auto-detected URL (build via the segments above). If you don't want to use auto-detection,
38+
* then replace this line with full URL (and sub-folder) and a trailing slash.
39+
*/
40+
define('URL_PUBLIC_FOLDER', '');
41+
define('URL_PROTOCOL', '//');
42+
define('URL_DOMAIN', $_SERVER['HTTP_HOST']);
43+
define('URL_SUB_FOLDER', str_replace(URL_PUBLIC_FOLDER, '', dirname($_SERVER['SCRIPT_NAME'])));
44+
define('URL', URL_PROTOCOL . URL_DOMAIN . URL_SUB_FOLDER);
45+
46+
/**
47+
* Configuration for: Database
48+
* This is the place where you define your database credentials, database type etc.
49+
*/
50+
define('DB_TYPE', 'mysql');
51+
define('DB_HOST', 'localhost');
52+
define('DB_NAME', 'msystem');
53+
define('DB_USER', 'msys');
54+
define('DB_PASS', 'root');
55+
56+
define('DB_CHARSET', 'utf8');

app/controllers/home.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
class Home extends Controller{
4+
5+
public function index(){
6+
/*
7+
* URL parameters can be recieved as an argument by specifying a variable for it in function declaration
8+
* EX: public function index($param1 , $param2){}
9+
* and can be used inside the function
10+
* - processed by the function model
11+
* - sent to the view
12+
*/
13+
14+
//loggedin user info
15+
global $loggedUser;
16+
//getting index model
17+
$index = $this->model('Index');
18+
//showing home/index view
19+
$this->view('home/index', ['user' => $loggedUser ]);
20+
}
21+
22+
23+
/*
24+
* login method includes a new object of login class
25+
* checks if user credentials [username,passwords] are provided using POST
26+
* if so it checks if user credentials are right using Login model
27+
* else it views the login page
28+
*/
29+
public function login(){
30+
31+
$login = $this->model('Login');
32+
if(isset($_POST['username'])){
33+
34+
$login->username = $_POST['username'];
35+
$login->password = $_POST['password'];
36+
$user = $login->userlogin();
37+
if(!$user){
38+
$this->view('home/login', [ 'error' => 'loginError' ]);
39+
}else{
40+
$this->view('home/index', [ 'msg' => 'loginSuccess','user' => $user ]);
41+
}
42+
}else{
43+
$this->view('home/login');
44+
}
45+
46+
47+
}
48+
49+
50+
public function logout(){
51+
$logout = $this->model('Logout');
52+
$logout->userLogout();
53+
$this->view('home/login',['msg' => 'logoutSuccess']);
54+
}
55+
}

app/core/App.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
class App{
4+
5+
6+
/*
7+
* definig defualt parameters if not specified by the user
8+
*/
9+
protected $controller = 'home';
10+
protected $method = 'index';
11+
protected $language = 'en';
12+
protected $params = [];
13+
14+
public function __construct(){
15+
16+
/*
17+
* GET request should be in the following form : URL/language/controller/method/parameters
18+
*/
19+
20+
//getting the request parameters
21+
$req = $this->parseUrl();
22+
23+
//setting the langauge to default language if not specified.
24+
25+
if(file_exists('../app/languages/' . $req[0])){
26+
define('LANGUAGE', array_shift($req));
27+
}else{
28+
define('LANGUAGE', $language);
29+
}
30+
31+
if(file_exists('../app/controllers/' . $req[0] . '.php')){
32+
$this->controller = $req[0];
33+
unset($req[0]);
34+
}
35+
36+
require_once '../app/controllers/' . $this->controller . '.php';
37+
$this->controller = new $this->controller;
38+
39+
if(isset($req[1])){
40+
if(method_exists($this->controller,$req[1])){
41+
$this->method = $req[1];
42+
unset($req[1]);
43+
}
44+
45+
}
46+
$this->params = $req ? array_values($req): [];
47+
48+
//sending the req array as parameters for the method function f(req[0],req[1] ..etc){}
49+
call_user_func_array([$this->controller,$this->method], $this->params);
50+
}
51+
52+
public function parseUrl(){
53+
if(isset($_GET['req'])){
54+
return $req = explode('/',filter_var(rtrim($_GET['req'],'/'),FILTER_SANITIZE_URL));
55+
}
56+
}
57+
58+
}

app/core/Controller.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
class Controller{
4+
5+
/* model function called to create an object of a model class
6+
* it checks user login first if not login it'll show login page
7+
* if the user is logged in it'll go on with the request
8+
*/
9+
10+
public function model($model){
11+
require_once '../app/models/Session.php';
12+
global $loggedUser;
13+
$session = new Session;
14+
$loggedUser = $session->checkLogin();
15+
/*
16+
* Comparing the requested model with user status
17+
* if user is loggedin can't request login model
18+
* if user is not loggedin it'll redirect him to login model
19+
*/
20+
21+
if(!$loggedUser && $model != 'Login'){
22+
header('Location: ' . URL . '/' . LANGUAGE .'/home/login');
23+
}elseif($loggedUser && $model == 'Login'){
24+
header('Location: ' . URL . '/' . LANGUAGE .'/home/index');
25+
}
26+
27+
require_once '../app/models/' . $model . '.php';
28+
return new $model();
29+
}
30+
31+
32+
/* view function called to create an object of a view class
33+
* it includes the neccesary language files
34+
* loads the required view.
35+
*/
36+
37+
public function view($view, $data = []){
38+
39+
/*
40+
* A main langauge file called main contains main variables like site name and description in different languages
41+
* every view should have the language file with the same name contains an associative array called
42+
* lang = array('key' => 'value');
43+
* in the language directory
44+
*/
45+
if(!isset($data['lang']['main'])){
46+
require_once("../app/languages/" . LANGUAGE . "/main.php");
47+
$data['lang']['main'] = $lang;
48+
}
49+
50+
$data['view'] = $view;
51+
if(!isset($data['lang'][$view])){
52+
require_once("../app/languages/" . LANGUAGE . "/". $view .".php");
53+
$data['lang'][$view] = $lang;
54+
}
55+
56+
//including the header, the view and the footer
57+
require_once '../app/views/layout/header.php';
58+
require_once '../app/views/' . $view . '.php';
59+
require_once '../app/views/layout/footer.php';
60+
}
61+
62+
}

app/init.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
/*
4+
* requiring main application scripts and config files
5+
*/
6+
require_once 'config/config.php';
7+
8+
require_once 'core/App.php';
9+
require_once 'Helper/Common.php';
10+
require_once 'Helper/Database.php';
11+
require_once 'core/Controller.php';

app/languages/en/home/index.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
$lang = array(
4+
'title' => 'Main',
5+
'loginSuccess' => 'LoggedIn successfully',
6+
'options' => 'User Options'
7+
);
8+
9+
?>

app/languages/en/home/login.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
$lang = array(
4+
'title' => 'LOGIN',
5+
'login' => 'login',
6+
'username' => 'user name',
7+
'password' => 'password',
8+
'logoutSuccess' => 'Successfully Logged out.',
9+
'loginError' => 'Wrong Username or Password.'
10+
);
11+
12+
?>

app/languages/en/main.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
/*
4+
* A langauge file contains main variables like site name and description ..etc
5+
* in different languages
6+
*/
7+
$lang = array(
8+
'site_name' => 'SITE NAME',
9+
'welcome' => 'SITE DESCRIPTION',
10+
'lang' => 'Language',
11+
'rights' => 'All Rights Reserved'
12+
);
13+
14+
?>

0 commit comments

Comments
 (0)