PHP OOP CRUD

Object Oriented Programming

  • Objects
  • Classes
  • "$this"
  • You probably know more
    about it by now...

Object

  • "An Object is an individual instance of the data structure defined by a class."

Class

  • "Classes are the blueprints of objects."
  • Classes have attributes :: $this->name
  • Classes have functions :: $this->getUserName()

Simple PHP OOP code

<?php
class A {
    public $foo = 1;
}

$a = new A;
$b = $a;
$b->foo = 2;
$c = new A;

echo $a->foo."\n";
echo $b->foo."\n";
echo $c->foo."\n";

Classes

Basic class

<?php
class User {
    protected $name;

    public function _construct() {
        //We do not use any constructor, just here for showing usage
    }

    //Getters
    public function getName() {
        return $this->name;
    }

    //Setters
    public function setName($name) {
        $this->name = $name;
    }
}

//Create new instance/ object
$a = new User;
//Set the name "Michiel"
$a->setName("Michiel");

//Show the name thru getName variable
echo $a->getName()."\n";
//Show name by just passing the attribute
echo $a->name;

public, private, protected, static?

  • Public - The item (variable/ function) can be used on the object outside the class (always)
  • Protected - The item can not be called outside the class
  • Private - The item can only be used within the object and will not be inherited/ extended to child-classes
  • Static - The item can be used without 'calling/creating' a class instance first (in PHP use :: to use static functions)

Class User

<?php
class User {
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printUser() {
        echo $this->public."\n";
        echo $this->protected."\n";
        echo $this->private."\n";
    }
}

$obj = new User();
echo $obj->public."\n";
echo $obj->protected."\n";
echo $obj->private."\n";
$obj->printUser();

Extends/ implements

  • For now, don't use the second (used by interfaces)
  • Extend does what the name says, it extends the previous class, all the attributes and functions are available in the child class
  • parent - child solutions

Class Doctor

<?php
Class Doctor extends User {
    public $public = 'Public2';

    public function printDocter() {
        echo $this->public."\n";
        echo $this->protected."\n";
        echo $this->private."\n";
    }

}

$obj2 = new Doctor();
echo $obj2->public."\n";
echo $obj2->protected."\n";
echo $obj2->private."\n";
$obj2->printDoctor();

$obj2->printUser();
<?php
class User {
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    public function printUser() {
        echo $this->public."\n";
        echo $this->protected."\n";
        echo $this->private."\n";
    }
}

Database

Create a Settings class

<?php

/**
 * Class DatabaseSettings basic class to store mysql-settings.
 */
class DatabaseSettings
{
    var $settings;

    /**
     * @return array
     */
    function getSettings()
    {
        $settings = [];
        // Database variables
        // Host name
        $settings['dbhost'] = 'localhost';
        // Database name
        $settings['dbname'] = 'phpoopcrud';
        // Username
        $settings['dbusername'] = 'phpoopcrud';
        // Password
        $settings['dbpassword'] = 'phpoopcrud';

        return $settings;
    }
}

Create a Database class

<?php

require_once( 'DatabaseSettings.php' );

class Database extends DatabaseSettings
{
    var $classQuery;
    var $link;

    var $errno = '';
    var $error = '';

    /**
     * Database constructor.
     */
    function __construct()
    {
        // Load settings from parent class
        $settings = DatabaseSettings::getSettings();

        // Get the main settings from the array we just loaded
        $host = $settings['dbhost'];
        $name = $settings['dbname'];
        $user = $settings['dbusername'];
        $pass = $settings['dbpassword'];

        // Connect to the database
        $this->link = new mysqli( $host , $user , $pass , $name );

        //Set the charset...
        mysqli_set_charset($this->link, 'utf8mb4');
    }

    /**
     * Database destructor
     */
    function __destruct() {
        $this->close();
    }

    // Executes a database query
    function query( $query )
    {
        $this->classQuery = $query;
        if ($value = $this->link->query( $query )) {
            return $value;
        } else {
            printf("Error: %s\n", $this->link->error);
        }
    }

    //Escape data
    function escapeString( $query )
    {
        return $this->link->real_escape_string( $query );
    }

    // Get the data return int result
    function numRows( $result )
    {
        return $result->num_rows;
    }

    //Get the last inserted ID
    function lastInsertedID()
    {
        return $this->link->insert_id;
    }

    // Get query using assoc method
    function fetchAssoc( $result )
    {
        return $result->fetch_assoc();
    }

    // Gets array of query results
    function fetchArray( $result , $resultType = MYSQLI_ASSOC )
    {
        return $result->fetch_array( $resultType );
    }

    // Fetches all result rows as an associative array, a numeric array, or both
    function fetchAll( $result , $resultType = MYSQLI_ASSOC )
    {
        return $result->fetch_all( $resultType );
    }

    // Get a result row as an enumerated array
    function fetchRow( $result )
    {
        return $result->fetch_row();
    }

    // Free all MySQL result memory
    function freeResult( $result )
    {
        $this->link->free_result( $result );
    }

    //Closes the database connection
    function close()
    {
        $this->link->close();
    }

    //Return the current error number and message
    function sql_error()
    {
        if( empty( $error ) )
        {
            $errno = $this->link->errno;
            $error = $this->link->error;
        }

        return $errno . ' : ' . $error;
    }
}

Use the code in the class

<?php

require_once('../database/Database.php');

/**
 * Class Model
 * Basic usage, extend this file to any database-table/ model
 */
class Model
{
    static $DB;
    static $table;

    function __construct($table) {
        $this->setTable($table);
        $this->setDB(new Database());
    }

    function setTable($table) {
        static::$table = $table;
        return;
    }

    function setDB($DB) {
        static::$DB = $DB;
        return;
    }

    static protected function getTable() {
        return static::$table;
    }

    static protected function getDB() {
        return static::$DB;
    }

    public function className() {
        return get_class($this);
    }

    public function save() {
        if (empty($this->id)) {
            $this->id = $this->saveNew();
        } else {
            $id = $this->id;
            $this->saveExisting($id);
        }
    }

    public function saveExisting($id) {
        $where = " WHERE id = ".$id;
        $updateQry = "id = $id";

        $modelColumns = $this->getAllColumnInformation();
        foreach ($modelColumns AS $column) {
            $c = $column[0];
            if ($c != 'id') {
                $cols[] = $c;
                if (strpos(strtolower($column[1]), 'int') !== false) {
                    $updateQry .= ", " . $c . " = " . $this->$c;
                } else {
                    $updateQry .= ", " . $c . " = '" . $this->getDB()->escapeString(htmlentities($this->$c)) . "'";
                }
            }
        }

        $qry = "UPDATE ".$this->getTable()." SET ".$updateQry.$where;
        $this->getDB()->query($qry);

        return true;
    }

    public function saveNew() {
        $modelColumns = $this->getAllColumnInformation();
        $cols = [];
        $values = [];
        foreach ($modelColumns AS $column) {
            $c = $column[0];
            if ($c != 'id') {
                $cols[] = $c;
                if (strpos(strtolower($column[1]), 'int') !== false) {
                    $values[] = $this->$c;
                } else {
                    $value = static::$DB->escapeString($this->$c);
                    $values[] = "'$value'";
                }
            }
        }

        $qry = "INSERT INTO ".$this->getTable()." (".implode(',', $cols).") VALUES (".implode(',', $values).");";

        static::$DB->query($qry);
        return $this->getDB()->lastInsertedID();
    }

    public static function all() {
        $model = static::childClass();
        $db = new Database();
        $allData = $db->query('SELECT id FROM '.static::$table)->fetch_all();
        $retData = [];
        foreach ($allData AS $obj)
            $retData[] = $model::find($obj[0]);

        return $retData;
    }

    public static function find($id) {
        $obj = static::childClass();
        $model = new $obj(static::getTable());

        $keys = $model->getColumns();
        $cols = [];
        foreach ($keys AS $k)
            $cols[] = $k;

        $theUser = static::$DB->query('SELECT * FROM '.static::$table.' WHERE id = '.$id)->fetch_row();

        foreach ($cols AS $key => $value)
            $model->$value = $theUser[$key];

        return $model;
    }

    public static function whereOne($array) {
        $obj = static::where($array);
        if (!empty($obj))
            return $obj[0];

        return null;
    }

    public static function where($array) {
        $model = static::childClass();
        $where = ' WHERE 1 = 1';
        foreach ($array AS $a)
            $where .= " AND $a[0] $a[1] $a[2]";

        $db = new Database();
        $qry = "SELECT id FROM ".static::$table.$where;
        $allData = $db->query($qry)->fetch_all();

        $retData = [];
        foreach ($allData AS $obj)
            $retData[] = $model::find($obj[0]);

        return $retData;
    }

    public static function getAllColumnInformation() {
        $db = new Database();
        $cols = $db->query("SHOW columns FROM ".static::$table.";")->fetch_all();
        $retData = [];
        foreach ($cols AS $c)
            $retData[] = $c;

        return $retData;
    }

    public static function getColumns() {
        $db = new Database();
        $cols = $db->query("SHOW columns FROM ".static::$table.";")->fetch_all();
        $retData = [];
        foreach ($cols AS $c)
            $retData[] = $c[0];

        return $retData;
    }

    public function delete() {
        $qry = 'DELETE FROM '.$this->getTable().' WHERE id = '.$this->id;

        return $this->getDB()->query($qry);
    }

    public static function childClass() {
        return get_called_class();
    }

    public function hasOne($model, $primary_key, $foreign_key) {
        return $model::whereOne([[$foreign_key,'=', $this->$primary_key]]);
    }

    public function BelongsTo($model, $primary_key, $foreign_key) {
        return $model::whereOne([[$primary_key, '=', $this->$foreign_key]]);
    }

    public function hasMany($model, $primary_key, $foreign_key) {
        return $model::where([[$foreign_key,'=', $this->$primary_key]]);
    }
}

Use it in a Model

<?php

require_once ('Model.php');

class User extends Model
{
    static $table = 'users';

    /**
     * Class constructor
     */
    function __construct() {
        parent::__construct(static::$table);
    }

}

Insert data

  • Rule one - never trust user input
  • Rule two - Really never trust user input
  •  

Script/ HTML tags removal

  • mysqli_real_escape_string - makes it SQL safe
    Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection
  • htmlentities - makes it HTML proof
    Convert all applicable characters to HTML entities
    (If you need HTML codes from DB, either store them or use PHP function html_entity_decode

Tip van flip

Webserver zonder XAMP

php -S localhost:8080
--
PHP 7.2.13 Development Server started at Tue Apr  9 11:58:05 2019
Listening on http://localhost:8080
Document root is /sites/php-oop-crud/public
Press Ctrl-C to quit.

PHP OOP CRUD

By CodePamoja

PHP OOP CRUD

Simple presentation for PHP OOP Crud system

  • 52