I've been working on a simple MVC PHP framework on and off for the last nearly 12 months, so I thought that I'd put it out there.The project began as a way to mentor and teach a junior (or a more junior than me) PHP developer, to show programming principles, OO methodologies and MVC-type file structures. The framework wasn't finished to my satisfaction as I moved on to a new employer in early 2017, but luckily I was allowed to continue its development, so I thought I'd put it out there.It's on GitHub here - I've called it FrameWork.php as I hope it to be as simple and stupid as I am. A quickly written quick start guide is here.I hope to finish the HTML builder so I can move on to making a MySQL/PDO query builder for the model core.The file structure is as follows:../application    ./controller    ./core    ./library    ./model    ./view../public_html    ./css    ./jsThe entry point in the framework is via the Index.php class (i.e., mysite.local/home) as follows:<?phpuse Application\Core\Framework\Core;require_once(serverPath('/core/FrameworkCore.php'));require_once(serverPath('/core/GlobalHelpers.php'));header('X-Content-Type-Options: nosniff');header('X-XSS-Protection: 1');header('Strict-Transport-Security: max-age=31536000; includeSubDomains');session_set_cookie_params(0, '/', getDomain(host(), ($https = isHttps()) ), $https, true);if(session_id() == ){    session_start();}## filepath ../public_htmlclass Index{    protected $core;    public $timeZone = Europe/London;    /**     * This will initiate the core to load the view     * according to the uri path, one may also     * change the default timezone for the project     * by altering the public $timeZone string above     * for a list of valid timezones, see:     * http://php.net/manual/en/timezones.php     *      * @param   na     * @author  sbebbington     * @date    24 Jan 2017 - 09:49:15     * @version 0.0.2     * @return       * @todo     */    public function __construct(){        $this->core = new \Application\Core\Framework\Core();        setTimeZone($this->timeZone);        $this->core->loadPage();    }}/** * This will correctly route to the application * directory on your server * * @param   string * @author  Shaun * @date    2 Feb 2017 - 13:01:13 * @version 0.0.2 * @return  string * @todo */function serverPath(string $routeTo = ''){    $_x = str_replace(\\, /, dirname(__FILE__)) . '/application';    $_x = str_replace(public_html/, , $_x);    $_x .= $routeTo;    return str_replace(//, /, $_x);}// Creates new instance and therefore initiates the controllers, models and views etc...$page = new Index();This will then call the core, which works out which view (page) to show, it works like this:<?phpnamespace Application\Core\Framework;require_once(serverPath('/core/HtmlBuilder.php'));## filepath ../application/coreclass Core extends \Application\Core\Framework\HtmlBuilder{    public $segment;    public $host;    public $allowedSegments = array(        'home',    );    public $pageController  = array(        'home'          => HomeController,    );    public $partial;    public $controller;    public $title;    public $description;    public $serverPath;    public $root;    public $flash;    public $filePath;    public $uriPath;    public $http;    private $errorReporting = array(        http://framework.php.local,        https://framework.php.local    );    private $allowedFileExts    = array(        'htm', 'html', 'asp', 'aspx', 'js', 'php', 'phtml',    );    public $canonical = '';    public function __construct(){        parent::__construct();        $this->host         = isHttps() ? https:// : http://;        $this->host         .= host();        if(in_array($this->host, $this->errorReporting)){            error_reporting(-1);            ini_set('display_errors', '1');        }        $this->uriPath  = '';        $page           = array_filter(explode('/', $_SERVER['REQUEST_URI']), 'strlen');        if(count($page)>1){            foreach($page as $key => $data){                if($key != count($page)){                    $this->uriPath  .= {$data}/;                }            }        }        $this->segment  = !empty($page) ? strtolower($page[count($page)]) : ;        if(!empty($_GET)){            $segment                    = explode('?', $this->segment);            $this->segment              = $segment[0];            if(isset($segment[1]) && strlen($segment[1])>0){                $_GET   = array();                $get    = explode(&, $segment[1]);                foreach($get as $data){                    $_data = explode(=, $data);                    $_GET[$_data[0]] = urldecode($_data[1]);                }            }        }        if(strpos($this->segment, .) > 0){            $segments           = explode(., $this->segment);                         if(in_array($segments[count($segments)-1], $this->allowedFileExts)){                $this->segment      = $segments[count($segments)-2];                $this->canonical    = <link rel=\canonical\ href=\{$this->host}/{$this->segment}\> . PHP_EOL;            }        }        $this->serverPath   = serverPath();        $this->root         = str_replace(\\, /, $_SERVER['DOCUMENT_ROOT']);        $this->controller   = new \stdClass();        $this->flash        = new \stdClass();        $this->partial      = array(            'header'    => serverPath(/view/partial/header.phtml),            'footer'    => serverPath(/view/partial/footer.phtml),        );    }    /**     * Sets the meta page titles in the views     *      * @param   string     * @author  sbebbington     * @date    2 Feb 2017 - 13:04:10     * @version 0.0.2     * @return  string     * @todo     */    public function setTitle(string $page = ''){        $titles = array(            'home'              => Example FrameWork.php skeleton site,        );        return $titles[{$page}];    }    /**     * Sets the meta page descriptions in the views     *      * @param   string     * @author  sbebbington     * @date    2 Feb 2017 - 13:04:47     * @version 0.0.1     * @return  string     * @todo     */    public function setDescription(string $page = ''){        $descriptions = array(            'home'              => The Skeleton,        );        return $descriptions[{$page}];    }    /**     * Bug fixed edition of the using ZF type view variables      *      * @param        * @author  sbebbington     * @date    2 Feb 2017 - 13:05:41     * @version 0.0.3a     * @return       * @todo     */    public function setView($instance, string $masterKey = ''){        foreach($instance as $key => $data){            if($masterKey == ''){                $this->$key = $data;            }else{                $this->$masterKey->$key = $data;            }        }    }    /**     * This will load the view and related controllers     * It has an added exception for Jamie's admin html     * template. This version should now allow Zend-alike     * view variables - so if you set an object in a page     * controller as $this->view->objName, you can use     * $this->objName in the PHP/HTML view or something.     *     * @param   na     * @author  sbebbington     * @date    6 Feb 2017 - 11:15:14     * @version 0.0.3     * @return  void     * @todo     */    public function loadPage(){        if($this->segment == ){            $this->segment      = 'home';        }        if(in_array($this->segment, $this->allowedSegments) == false || !file_exists(serverPath(/view/{$this->uriPath}{$this->segment}.phtml))){            $this->setView(array(_404Error => 1));            $this->title        = '404 error - page not found, please try again';            $this->description  = 'There\'s a Skeleton in the Sandbox';            require_once(serverPath(/view/404.phtml));            exit;        }        if(in_array($this->segment, $this->allowedSegments) == true){            $this->title        = $this->setTitle($this->segment);            $this->description  = $this->setDescription($this->segment);            foreach($this->pageController as $instance => $controller){                if($this->segment == $instance){                    require_once(serverPath(/controller/{$controller}.php));                    $this->controller->$instance = new $controller();                    if(isset($this->controller->$instance->view)){                        $this->setView($this->controller->$instance->view);                        $this->controller->$instance->view = null;                    }                }            }            if(isset($_SESSION['flashMessage']) && !empty($_SESSION['flashMessage'])){                $this->setView($_SESSION['flashMessage'], flash);            }            require_once(serverPath(/view/{$this->uriPath}{$this->segment}.phtml));        }    }}Each view will load a controller instance, routed in the ../application/controller directory, by default there is a ControllerCore class and a page controller class (assumes HomeController.php by default), as follows:<?phpnamespace Application\Controller;use Application\Library;require_once(serverPath('/library/Library.php'));## filepath ../application/controllerclass ControllerCore{    public $post;    public $view;    public $lib;    public $sql;    public $host;    public function __construct(){        $this->lib      = new \Application\Library\Library();        if(!isset($_SESSION['flashMessage'])){            $_SESSION['flashMessage']   = array();        }        if(empty($this->post) || $this->post == null){            $this->post     = array();        }        if(!empty($_POST)){            $this->setPost();        }        $this->view             = new \stdClass();                $this->host             = host();    }    /**     * Sanatizes posted data     *     * @param   Array     * @author  Linden && Shaun     * @date    7 Oct 2016 14:54:10     * @version 0.0.3     * @return  na     * @todo     */    public function setPost(){        foreach($_POST as $key => $data){            $this->post[$key]   = is_string($data) ? trim($data): $data;        }    }    /**     * This should empty the super global $_POST and the controller $this->post     *     * @param   na     * @author  Shaun     * @date    16 Jun 2016 11:25:04     * @version 0.0.1     * @return  array     * @todo     */    public function emptyPost(){        $_POST      = array();        $this->post = $_POST;    }    /**     * Clears PHP session cookies     *     * @param   na     * @author  Shaun     * @date    14 Sep 2016 14:29:23     * @version 0.0.2     * @return     * @todo     */    public function emptySession(){        if(session_id() != ){            session_destroy();        }           $this->session  = null;    }    /**     * Sets flash messages (recommend using string for value param)     *     * @param   string, string | int | boolean     * @author  Shaun     * @date    14 Sep 2016 09:48:53     * @version 0.0.1     * @return  na     * @todo     */    public function setFlashMessage($key, $value){        $_SESSION['flashMessage'][$key] = $value;    }    /**     * Checks if flash message exists     *     * @param   string     * @author  Shaun     * @date    14 Sep 2016 10:18:04     * @version 0.0.1     * @return  boolean     * @todo     */    public function getFlashMessage($key){        return isset($_SESSION['flashMessage'][$key]) ? true : false;    }    /**     * Clears flash messages     *     * @param   string|array     * @author  Shaun     * @date    15 Sep 2016 10:40:49     * @version 0.0.1     * @return  na     * @todo     */    public function clearFlashMessage($key){        if(is_array($key)){            foreach($key as $_key => $_data){                $_SESSION['flashMessage'][$_data]   = null;            }        }else{            $_SESSION['flashMessage'][$key]         = null;        }    }}And the home controller:<?phprequire_once (serverPath('/controller/ControllerCore.php'));require_once (serverPath('/model/HomeModel.php'));## filepath ../application/controllerclass HomeController extends \Application\Controller\ControllerCore{    public function __construct(){        parent::__construct();        $this->sql              = new HomeModel();        foreach($this->sql->getView() as $key => $data){            $key                = $this->lib->convertSnakeCase($key);            $this->view->$key   = htmlspecialchars_decode($data);        }        // if(isset($this->post['submit'])){            // Do something with the posted data here, but for now            // we'll simply see the contents of the posted data            // $this->lib->debug($this->post, true);        // }    }}Any feedback is appreciated.
Simple OO MVC PHP framework
php;object oriented;mvc