SkillAgentSearch skills...

MiniPHP

A small, simple PHP MVC framework skeleton that encapsulates a lot of features surrounded with powerful security layers.

Install / Use

/learn @OmarElgabry/MiniPHP
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

miniPHP

miniPHP

Build Status Scrutinizer Code Quality Code Climate Dependency Status

Latest Stable Version License

A small, simple PHP MVC framework skeleton that encapsulates a lot of features surrounded with powerful security layers.

miniPHP is a very simple application, useful for small projects, helps to understand the PHP MVC skeleton, know how to authenticate and authorize, encrypt data and apply security concepts, sanitization and validation, make ajax calls and more.

It's not a full framework, nor a very basic one but it's not complicated. You can easily install, understand, and use it in any of your projects.

It's indented to remove the complexity of the frameworks. Things like routing, authentication, authorization, manage user session and cookies, and so on are not something I've invented from the scratch, however, they are aggregation of concepts already implemented in other frameworks, but, built in a much simpler way, So, you can understand it, and take it further.

If you need to build bigger application, and take the advantage of most of the features available in frameworks, you can see CakePHP, Laravel, Symphony.

Either way, It's important to understand the PHP MVC skeleton, and know how to authenticate and authorize, learn about security issues and how can you defeat against, and how to build you own application using the framework.

Documentation

Full Documentation can be also found here — created by GitHub automatic page generator.

Index

Demo <a name="live-demo"></a>

A live demo is available here. The live demo is for the demo application built on top of this framework in this section. Thanks to @Everterstraat.

Some features mighn't work in the demo.

Installation <a name="installation"></a>

Install via Composer

	composer install

Routing <a name="routing"></a>

Whenever you make a request to the application, it wil be directed to index.php inside public folder. So, if you make a request: http://localhost/miniPHP/User/update/412 . This will be splitted and translated into

  • Controller: User
  • Action Method: update
  • Arguemtns to action method: 412

In fact, htaccess splits everything comes after http://localhost/miniPHP and adds it to the URL as querystring argument. So, this request will be converted to: http://localhost/miniPHP?url='User/update/412' .

Then App Class, Inside splitUrl(), will split the query string $_GET['url'] into controller, action method, and any passed arguments to action method.

In App Class, Inside run(), it will instantiate an object from controller class, and make a call to action method, passing any arguments if exist.

Controller <a name="controller"></a>

After the App Class intantiates controller object, It will call $this->controller->startupProcess() method, which in turn will trigger 3 consecutive events/methods:

  1. initialize(): Use it to load components
  2. beforeAction(): Perform any logic actions before calling controller's action method
  3. triggerComponents(): Trigger startup() method of loaded components

The constructor of Controller Class shouldn't be overridden, instead you can override the initialize() & beforeAction() methods in the extending classes.

After the startup process of the constrcutor finishes it's job, Then, the requested action method will be called, and arguments will be passed(if any).

Components(Middlewares) <a name="components"></a>

Components are the middlewares. They provide reusable logic to be used as part of the controller. Authentication, Authorization, Form Tampering, and Validate CSRF Tokens are implemented inside Components.

It's better to pull these pieces of logic out of controller class, and keep all various tasks and validations inside these Components.

Every component inherits from the base/super class called Component. Each has a defined task. There are two components, one for called Auth for Authentication and Authorization, and the other one called Security for other Security Issues.

They are very simple to deal with, and they will be called inside controller constructor.

Authentication <a name="authentication"></a>

Is user has right credentials?

Session<a name="session"></a>

The AuthComponent takes care of user session.

  • Prevent Session Concurrency
    • There can't be 2 users logged in with same user credentials.
  • Defeat against Session Hijacking & Fixation
    • HTTP Only with session cookies
    • Whenever it's possible, It's Highly Recommended to use Secured connection(SSL).
    • Regenerate session periodically and after actions like login, forgot password, ...etc.
    • Validate user's IP Address and User agent(initially will be stored in session). Although they can be faked, It's better to keep them as part of validation methods.
  • Session Expiration
    • Session will expire after certain duration(>= 1 day)
    • Session cookie in browser is also configured to be expired after (>= 1 week)
  • Session accessible only through the HTTP protocol
    • This is important so sessions won't be accessible by JS.

Cookies<a name="cookies"></a>

  • Remember Me Tokens
    • User can keep himself logged in using cookies
    • HTTP Only with cookies
    • Whenever it's possible, It's Highly Recommended to use Secured connection(SSL).
    • Cookies stored in browser are attached with tokens and Encrypted data
    • Cookies in browser are also configured to be expired after (>= 2 weeks)

Authorization <a name="authorization"></a>

Do you have the right to access or to perform X action?. The Auth Component takes care of authorization for each controller. Thus, each controller should implement isAuthorized() method. What you need to do is to return boolean value.

So, for example, in order to check if current user is admin or not, you would do something like this:

    // AdminController

    public function isAuthorized(){

        $role = Session::getUserRole();
        if(isset($role) && $role === "admin"){
            return true;
        }
        return false;
    }

If you want to take it further and apply some permission rules, There is a powerful class called Permission responsible for defining permission rules. This class allows you to define "Who is allowed to perform specific action method on current controller".

So, for example, in order to allow admins to perform any action on notes, while normal users can only edit their notes:

   // NotesController
   
   public function isAuthorized(){

        $action = $this->request->param('action');
        $role 	= Session::getUserRole();
        $resource = "notes";

		// only for admins
		// they are allowed to perform all actions on $resource
        Permission::allow('admin', $resource, ['*']);

		// for normal users, they can edit only if the current user is the owner
		Permission::allow('user', $resource, ['edit'], 'owner');

        $noteId = $this->request->data("note_id");
        $config = [
            "user_id" => Session::getUserId(),
            "table" => "notes",
            "id" => $noteId
        ];

		// providing the current user's role, $resource, action method, and some configuration data
		// Permission class will check based on rules defined above and return boolean value
		return Permission::check($role, $resource, $action, $config);
    }

Related Skills

View on GitHub
GitHub Stars162
CategoryDevelopment
Updated6d ago
Forks52

Languages

PHP

Security Score

100/100

Audited on Mar 24, 2026

No findings