PHP Classes

File: DatabaseTrait.php

Recommend this page to a friend!
  Classes of John ieroni   Database Trait   DatabaseTrait.php   Download  
File: DatabaseTrait.php
Role: Class source
Content type: text/plain
Description: A CRUD workhorse for classes
Class: Database Trait
Trait that implement SQL database CRUD operations
Author: By
Last change: update to use prepared statements instead of input sanitization via real_escape_string()
Date: 12 days ago
Size: 8,926 bytes
 

Contents

Class file image Download
<?php

trait DatabaseTrait
{
   
/**
     * Name of the primary field in the database/object.
     * @return string name of field
     */
   
abstract static function getPrimaryField(): string;

   
/**
     * Name of the table for this class.
     * @return string name of table
     */
   
abstract static function getTable(): string;

   
/**
     * Name of the Object for this class.
     * @param int $id
     * @return static name of whatever object in use
     */
   
abstract static function getObject(int $id): static;

   
/**
     * Returns the primary key, usually an int.
     * @return int
     */
   
function getID(): int
   
{
        return
$this->{static::getPrimaryField()};
    }

   
/**
     * Inserts a new record into the table.
     *
     * @param array $array An associative array representing the values to be inserted
     * @return int The ID of the newly inserted record
     * @throws Exception
     */
   
static function insert(array $array): int
   
{
       
$db = new Database();
        return
$db->insert(static::getTable(), $array);
    }

   
/**
     * Updates the record in the table with the specified values.
     *
     * @param array $array The array of key-value pairs representing the columns and their new values.
     * @return bool Returns true if the update was successful, false otherwise.
     * @throws Exception Thrown if the input array is empty.
     */
   
function update(array $array): bool
   
{
       
$db = new Database();
        return
$db->update(static::getTable(), $array, [static::getPrimaryField() => $this->getID()]);
    }

   
/**
     * Delete the record from the table.
     * @return bool Returns true if the record is successfully deleted, otherwise false.
     * @throws Exception
     */
   
function delete(): bool
   
{
       
$db = new Database();
        return
$db->delete(static::getTable(), [static::getPrimaryField() => $this->getID()]);
    }

   
/**
     * Retrieves all records from the table, with optional order by clause.
     *
     * @param array $orderBy Optional order by clause in the form of ['column' => 'ASC/DESC']
     * @return static[] An array of objects representing the records
     * @throws Exception
     */
   
static function all(array $orderBy = []): array
    {
       
$db = new Database();
       
$results = $db->select(static::getTable(), [static::getPrimaryField()], [], $orderBy);
        return
array_map(fn($row) => static::getObject($row[static::getPrimaryField()]), $results);
    }

   
/**
     * Get an array of objects based on a set of WHERE conditions
     *
     * @param array $whereFields An associative array representing the WHERE conditions. The keys are the column names
     * and the values are the column values. If a value is null, it will be treated as a NULL condition.
     * @param array $orderBy An associative array representing the ORDER BY conditions. The keys are the column names
     * and the values are the sort direction (ASC or DESC).
     * @return static[] An array of objects.
     * @throws Exception
     */
   
static function where(array $whereFields = [], array $orderBy = [], array $whereNot = []): array
    {
       
$db = new Database();
       
$results = [];

       
$sql = "SELECT `" . static::getPrimaryField() . "` FROM `" . static::getTable() . "`";
       
$clauses = [];
       
$types = '';
       
$params = [];

        foreach (
$whereFields as $col => $val) {
            if (
$val === null) {
               
$clauses[] = "$col IS NULL";
            } else {
               
$clauses[] = "$col = ?";
               
$types .= $db->getParamType($val);
               
$params[] = $val;
            }
        }

        foreach (
$whereNot as $col => $val) {
            if (
$val === null) {
               
$clauses[] = "$col IS NOT NULL";
            } else {
               
$clauses[] = "$col != ?";
               
$types .= $db->getParamType($val);
               
$params[] = $val;
            }
        }

        if (
$clauses) {
           
$sql .= " WHERE " . implode(" AND ", $clauses);
        }

        if (!empty(
$orderBy)) {
           
$orderParts = [];
            foreach (
$orderBy as $col => $dir) {
               
$orderParts[] = "$col $dir";
            }
           
$sql .= " ORDER BY " . implode(', ', $orderParts);
        }

       
$stmt = $db->prepareAndExecute($sql, $types, $params);
       
$result = $stmt->get_result();

        while (
$row = $result->fetch_assoc()) {
           
$results[] = static::getObject($row[static::getPrimaryField()]);
        }
        return
$results;
    }

   
/**
     * Retrieves a single, unique object based on the provided filter conditions.
     * If the query results in more than one object, an exception is thrown to indicate
     * that the object is not unique. If no object matches the conditions, null is returned.
     *
     * @param array $whereFields Associative array of field-value pairs to filter the query.
     * @return static|null The unique object matching the filter conditions, or null if no match is found.
     * @throws Exception If more than one result is found for the given filter conditions.
     */
   
static function whereUnique(array $whereFields): ?static
    {
       
$results = static::where($whereFields);
        if (
count($results) > 1) {
            throw new
Exception("Object is not unique");
        }
        return
$results[0] ?? null;
    }

   
/**
     * @param array $likeFields
     * @param array $orderBy
     * @return array
     * @throws Exception
     */
   
static function whereLIKE(array $likeFields = [], array $orderBy = []): array
    {
       
$db = new Database();
       
$sql = "SELECT `" . static::getPrimaryField() . "` FROM `" . static::getTable() . "`";
       
$clauses = [];
       
$types = '';
       
$params = [];

        foreach (
$likeFields as $col => $val) {
            if (
$val === null) {
               
$clauses[] = "$col IS NULL";
            } else {
               
$clauses[] = "$col LIKE ?";
               
$types .= 's';
               
$params[] = "%$val%";
            }
        }

        if (!empty(
$clauses)) {
           
$sql .= " WHERE " . implode(" OR ", $clauses);
        }

        if (!empty(
$orderBy)) {
           
$orderParts = [];
            foreach (
$orderBy as $col => $dir) {
               
$orderParts[] = "$col $dir";
            }
           
$sql .= " ORDER BY " . implode(', ', $orderParts);
        }

       
$stmt = $db->prepareAndExecute($sql, $types, $params);
       
$result = $stmt->get_result();

       
$objects = [];
        while (
$row = $result->fetch_assoc()) {
           
$objects[] = static::getObject($row[static::getPrimaryField()]);
        }
        return
$objects;
    }

   
/**
     * Loads the count of all entities with a given where condition (filter specified by
     * $conditions array)
     *
     * @param array<string, mixed> $conditions
     * @return int number of matching results in the DB
     * @throws Exception
     */
   
static function countWhere(array $conditions = []): int
   
{
       
$db = new Database();
        return
$db->count(static::getTable(), static::getPrimaryField(), $conditions);
    }

   
/**
     * Loads the count of all entities within the table
     * @return int number of matching results in the DB
     * @throws Exception
     */
   
static function countAll(): int
   
{
       
$db = new Database();
        return
$db->count(static::getTable(), static::getPrimaryField());
    }

   
/**
     * This function takes in an array of IDs (or names, if names are unique
     * and you have the capability to look up on names), and returns an array of
     * objects of this type, all ready to be used.
     *
     * This will then run through a "duplicate check" (where any duplicate objects are
     * culled) and cached locally.
     * @param int[] $ids array of IDs to load
     * @return static[]
     * @throws Exception
     */
   
static function load(array $ids): array
    {
        if (empty(
$ids)) return [];

       
$db = new Database();
       
$placeholders = implode(',', array_fill(0, count($ids), '?'));
       
$types = str_repeat('i', count($ids));

       
$sql = "SELECT `" . static::getPrimaryField() . "` FROM `" . static::getTable() . "` WHERE `" . static::getPrimaryField() . "` IN ($placeholders)";
       
$stmt = $db->prepareAndExecute($sql, $types, $ids);
       
$result = $stmt->get_result();

       
$objects = [];
        while (
$row = $result->fetch_assoc()) {
           
$objects[] = static::getObject($row[static::getPrimaryField()]);
        }
        return
$objects;
    }
}