/MVC-Framework

Custom PHP MCV framework from scratch

Primary LanguagePHP

Introduction

A simple PHP MVC framework built from scratch.

Pre-requisites

  • XAMPP or Manual created environment with:

    • PHP 8.0+

        sudo apt update
        sudo apt install lsb-release ca-certificates apt-transport-https software-properties-common -y
        sudo add-apt-repository ppa:ondrej/php
        sudo apt install php8.0 -y
        sudo apt install php8.0-cli php8.0-common php8.0-mbstring -y
      
    • MySQL DB

        sudo apt update
        sudo apt install mysql-server
      
    • Apache2

        sudo apt update
        sudo apt install apache2
      
  • Composer

      sudo apt update
      cd ~
      curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
    
      HASH=`curl -sS https://composer.github.io/installer.sig`
      php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
    
      sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
    
      composer
    

Installation

  • Create app using

      composer create-project momik/simplemvc example-app
    
  • Navigate to ' public '

      cd example-app
      cd public  
    
  • Serve app at port:8080

      php -S localhost:8080
    

Getting Started

  • DATABASE

    Edit the .env file to configure database.
    • Set database name in DB_DSN = ......dbname ='test_db'
    • Set user in DB_USER = root
    • Set password in DB_PASSWORD = password
  • Migration

    Run migrations.php to initialize database
    php migrations.php
    
    You can manipulate database and tables by adding scripts in ' migrations ' directory.
    • There is no strict naming convention for migration scripts.
    • Migration scripts need to be a class with classname = filename.
    • Migration class need to have up() and down() method.
    • Run migrations.php so that changes take effect.

Documentation

  • Entry point

    • The public/index.php is the entry point for the application.
    • public/index.php determines how HTTP requests are handled.

    Syntax:

    Router::METHOD('/url', callback);
    

    Example:

    Anonymous functions:

    Router::GET('/test', function(){
      //some code here
      return "This is test."
    });
    
    Router::POST('/test', function(){
     //some code here
     return "This is test."
    });
    

    Controller functions:

    Router::GET('/login', [LoginController::class, 'index']);
    
    Router::POST('/login', [LoginController::class, 'login']);
    
  • Controllers

    • Write Controllers in controllers directory.
    • YourController must extend Controller.
    • Controllers must contain property: public array $params[]
    • Members/elements of this array property can be accessed as separate variable in respective view.
    • Example.
      $this->params['message'] = "This is message";  //in controller
      
      <p>
         <?php echo $message;?> // in view
      </p> 
      
      $this->params['user']['id'] = 5;  //in controller
      $this->params['user']['name'] = "foo";  
      $this->params['user']['email'] = "bar"; 
      
      <p>
      <?php echo $user['id'];?> // in view
      <?php echo $user['name'];?> 
      <?php echo $user['email'];?> 
      </p> 
      
  • Models

    • Write Data models in models directory.
    • YourModel must extend Model.
    • YourModel must implement methods:
      • tableName( ). Returns ( string ) name of table .
      • primaryKey( ). Returns ( string ) primary field name .
      • fields( ). Returns (array of string ) containing name of all fields except primary field. .
  • Views

    • Views can be rendered through controller by:
       return View::make('home', $this->params);
      
    • Write Views in views directory.
    • Views must declare document title by:
      //inside view
      <?php
      /** @var  $this momik\simplemvc\core\View */
      $this->title = "Document title";
      ?>
      
  • Layouts

    • You can have multiple layouts.
    • Write layouts in views/layouts
    • Set layout through respective controller by:
      $this->setLayout('layoutName');
      
  • Sessions

    • Sessions made easy.
    • Setting, Getting, Unsetting Session
      SESSION::set('key', 'value'); //setting session
      SESSION::get('key); //accessing set session
      SESSION::remove('key); //accessing set session
      
    • Setting and Getting Session Flash
      SESSION::setFlash('key', 'value'); //setting session flash 
      SESSION::getFlash('key); //getting session flash msg
      
  • Form Validation

    • Access predefined validations. ( Study core/Validation.php for all available validations. )
    • Example:
        $formFields = array(
                            "email"=>"foo@bar.com",
                             "password"=>"fooBar#123"
                           );
      
        $errors = Validation::validate($formFields)  
        //returns array string of error messages.
      
        if ( empty($errors) ) {
           echo "All ok";      
        } else {
            foreach ( $errors as $error ) {
                echo $error."<br>"
            }
        }
      
  • Form and Field Components

    • Create forms using the Form and Field Component.
    • Syntax:
      Form::open('actionUrl', 'requestMethod');
      echo Form::field('inputType', [assoc array of attribute and values], 'optionalErrorMsg');
      echo "<button type='submit'>Login</buton>";
      Form::close();
      
    • Example:
        Form::open('', "post");
        echo Form::field("email", ['name' => 'email', 'placeholder'=>'Email here'], $errors['email'] ?? '');
        echo Form::field("password", ['name' => 'password', 'placeholder'=>'Password here'], $errors['password'] ?? '');
        echo "<button type='submit' class='btn btn-md btn-primary my-2 col-12'>Login</buton>";
        Form::close();
      
  • Basic CRUD Operation

    The core/Model.php contains commonly used CRUD operation.
    These operations are inherited by all dataModels in the models directory.
    Operations:

    Operation Method Params Description
    Create record save() - Inserts a record into table.
    Read Single record by ID fetch($id) $id Fetches record based on primary key.
    Read Single record by XYZ findOne($where) $where $where is a assoc array. Fetches record where multiple WHERE conditions are satisfied.
    Update record update($id) $id Updates single record based on id.
    Delete record delete($id) $id Deletes single record based on id.

FAQs

1. What does $request->getMethod() do?

Returns HTTP Request method. Returns get, post, put, etc.

2. What does $request->getBody() do?

Returns assoc array of HTTP Request content. Mostly used to get POST data from form.

3. What does $object->findOne($assocArray) do?

Returns associative array from respective table where, fields and values match key and value of $assocArray.

4. What does $object->initializeProperty($assocArray) do?

Returns void. Keys of the associative array are initialized as properties of object, values of associative array are set as respective property value.