Overview
Models in S-PHP provide an elegant way to interact with database tables. The Models class offers built-in methods for creating, reading, updating, and deleting records with automatic prepared statement protection.
Creating a Model
Models are located in the app/Models directory and extend the Sphp\Core\Models class.
<? php
namespace App\Models ;
use Sphp\Core\ Models ;
class Users extends Models
{
public function __construct ()
{
$this -> table = "users" ;
$this -> fillables = [ 'email' , 'name' , 'password' , 'verified' ];
parent :: __construct ();
}
public function save ( $data )
{
$data [ 'password' ] = password_hash ( $data [ 'password' ], PASSWORD_BCRYPT );
return $this -> create ( $data );
}
}
Model Properties
The name of the database table this model represents
Array of column names that can be mass-assigned. Provides protection against unauthorized fields.
Environment configuration automatically loaded from config
Database instance for executing queries
Array of fields to hide from query results (e.g., passwords)
Create Records
The create() method inserts a new record into the database.
Associative array of data to insert. Only fields listed in $fillables will be inserted.
public function create ( $request )
{
try {
$data = array_intersect_key ( $request , array_flip ( $this -> fillables ));
if ( empty ( $data )) {
throw new \Exception ( "No valid fields provided for insertion." );
}
$columns = implode ( ", " , array_keys ( $data ));
$placeholders = implode ( ", " , array_fill ( 0 , count ( $data ), "?" ));
$query = " INSERT INTO { $this -> table } ({ $columns }) VALUES ({ $placeholders })" ;
$result = $this -> db -> query ( $query , array_values ( $data ));
return $result ;
} catch ( \ Exception $e ) {
dd ( $e -> getMessage ());
}
}
Example Usage
$user = new Users ();
$user -> create ([
'email' => '[email protected] ' ,
'name' => 'John Doe' ,
'password' => 'hashed_password' ,
'verified' => 1
]);
Update Records
The update() method modifies an existing record.
Associative array of data to update. Only fields in $fillables will be updated.
The ID of the record to update
public function update ( $request , $id )
{
$data = array_intersect_key ( $request , array_flip ( $this -> fillables ));
if ( empty ( $data )) {
throw new \Exception ( "No valid fields provided for updating." );
}
$updateFields = implode ( ", " , array_map ( function ( $field ) {
return " $field = ?" ;
}, array_keys ( $data )));
$query = " UPDATE { $this -> table } SET $updateFields WHERE id = ?" ;
$params = array_values ( $data );
$params [] = $id ;
$this -> db -> query ( $query , $params );
}
Example Usage
$user = new Users ();
$user -> update ([
'name' => 'Jane Doe' ,
'verified' => 1
], 123 );
Delete Records
The delete() method removes a record from the database.
The ID of the record to delete
public function delete ( $id )
{
if ( empty ( $id )) {
throw new \Exception ( "No valid fields provided for updating." );
}
$query = " DELETE FROM { $this -> table } WHERE id = ?" ;
$params [] = $id ;
$this -> db -> query ( $query , $params );
}
Example Usage
$user = new Users ();
$user -> delete ( 123 );
Select Records
The select() method queries records with flexible filtering options.
Array of column names to select (e.g., ['id', 'name', 'email'] or ['*'])
Associative array of WHERE conditions (e.g., ['status' => 'active', 'role' => 'admin'])
ORDER BY clause (e.g., 'created_at DESC')
Maximum number of records to return. 0 means no limit.
public function select ( array $columns , array $where = [], string $orderBy = '' , int $limit = 0 )
{
if ( empty ( $columns )) {
throw new \Exception ( "No valid fields provided for selection." );
}
$columns_in_string = implode ( ', ' , $columns );
$where_string = '' ;
$params = [];
if ( ! empty ( $where )) {
$conditions = [];
foreach ( $where as $column => $value ) {
$conditions [] = " $column = ?" ;
$params [] = $value ;
}
$where_string = 'WHERE ' . implode ( ' AND ' , $conditions );
}
$order_by_string = $orderBy ? "ORDER BY $orderBy " : '' ;
$limit_string = $limit > 0 ? "LIMIT $limit " : '' ;
$query = " SELECT { $columns_in_string } FROM { $this -> table } { $where_string } { $order_by_string } { $limit_string }" ;
$query = preg_replace ( '/ \s + /' , ' ' , trim ( $query ));
return $this -> db -> query ( $query , $params );
}
Example Usage
$user = new Users ();
// Select all columns
$allUsers = $user -> select ([ '*' ]);
// Select specific columns with WHERE clause
$activeUsers = $user -> select (
[ 'id' , 'name' , 'email' ],
[ 'verified' => 1 ]
);
// With ordering and limit
$recentUsers = $user -> select (
[ '*' ],
[ 'verified' => 1 ],
'created_at DESC' ,
10
);
Find by ID
The findByID() method retrieves a single record by its ID.
The ID of the record to find
public function findByID ( $id )
{
if ( empty ( $id )) {
throw new \Exception ( "No valid fields provided for selection." );
}
$query = " SELECT * FROM { $this -> table } WHERE id = $id " ;
$result = $this -> db -> query ( $query );
return $result [ 0 ];
}
Example Usage
$user = new Users ();
$user = $user -> findByID ( 123 );
echo $user [ 'name' ]; // Access user data
Custom Model Methods
You can add custom methods to your models for specific business logic:
class Users extends Models
{
public function save ( $data )
{
$data [ 'password' ] = password_hash ( $data [ 'password' ], PASSWORD_BCRYPT );
return $this -> create ( $data );
}
public function findByEmail ( $email )
{
return $this -> select ([ '*' ], [ 'email' => $email ])[ 0 ] ?? null ;
}
public function getVerifiedUsers ()
{
return $this -> select ([ '*' ], [ 'verified' => 1 ]);
}
}
Security Features
Mass Assignment Protection Only fields in $fillables can be assigned, preventing unauthorized database modifications.
Prepared Statements All queries use PDO prepared statements, protecting against SQL injection attacks.
Input Filtering Data is automatically filtered using array_intersect_key() to match fillable fields.
Exception Handling Built-in exception handling for common errors and edge cases.
Best Practices
Always define fillables : Protect your database by explicitly listing allowed fields
Use custom methods : Create specific methods for complex queries or business logic
Hash passwords : Always hash passwords in custom save methods
Validate input : Validate data before passing to model methods
Handle exceptions : Wrap model operations in try-catch blocks in your controllers
Next Steps
Database Learn about the underlying Database class and raw queries
Controllers See how to use models in your controllers