The following classes are used for web development. And I was wondering if I'm implementing them correctly specially the Base class.
This is a version 2.0 of the question the classes are as follows:
- MyPDO
- Session
- Security
- Base
Examples:
<?php
//using the autoloader
require "../classes/autoloader.php";
// checking if the user isn't logged in so he can loggin
$session = new Session;
if ($session->is_logged_in()) {
Base::location();
}
// set session variables used by the class "logging" the user in
$session->initialize_user_session($user["admin"], $_POST["username"]);
//Redirect to another webpage and exit
Base::location();
//Encoding output to prevent XSS
$html = "<script>alert('XSS')</script>";
echo "<h1>". Security::clean_html($html) ."</h1>";
My doubts are should I use the constants and is base class any good since it only has two functions and they are not that related? The code is:
MyPDO class (made from phpdelusions.net) :
define("DB_HOST", "localhost");
define("DB_NAME", "root");
define("DB_USER", "root");
define("DB_PASS", "root");
define("DB_CHAR", "utf8mb4");
class MyPDO extends PDO
{
public function __construct($dsn = NULL, $username = DB_USER, $password = DB_PASS, $options = [])
{
$default_options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];
$options = array_replace($default_options, $options);
$dsn = $dsn ?? "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHAR;
parent::__construct($dsn, $username, $password, $options);
}
public function run($sql, $args = NULL)
{
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
Session class:
/*
* Session handling class
*/
define("ADMIN_VALUE_KEY", "admin");
define("LOGIN_VALUE_KEY", "logged_in");
define("USER_ID_KEY", "user_id");
define("CSRF_TOKEN_KEY", "csrf_token");
define("LOCATION_DEFAULT_DIR", "index.php");
class Session
{
public function __construct()
{
session_start();
}
public function initialize_user_session($admin, $user_id) {
$_SESSION[ADMIN_VALUE_KEY] = $admin;
$_SESSION[LOGIN_VALUE_KEY] = true;
$_SESSION[USER_ID_KEY] = $user_id;
$_SESSION[CSRF_TOKEN_KEY] = Security::generate_token(64);//bin2hex(random_bytes(32));
}
public function logout(){
session_destroy();
Base::location();
}
public function is_logged_in() {
return (!empty($_SESSION[USER_ID_KEY]));
}
public function is_admin() {
return (!empty($_SESSION[ADMIN_VALUE_KEY]));
}
/*
* Check functions
*/
public function check_token($token, $dir = LOCATION_DEFAULT_DIR)
{
if (!hash_equals($_SESSION[CSRF_TOKEN_KEY], $token)) {
Base::location($dir);
}
}
public function check_login($dir = LOCATION_DEFAULT_DIR)
{
if (empty($_SESSION[USER_ID_KEY])) {
Base::location($dir);
}
}
public function check_admin($dir = LOCATION_DEFAULT_DIR)
{
if (empty($_SESSION[ADMIN_VALUE_KEY])) {
Base::location($dir);
}
}
}
Security class:
class Security
{
public static function generate_token(int $length) : string {
return bin2hex(random_bytes($length/2));
}
public static function clean_html(string $html) : string {
return htmlspecialchars($html, ENT_QUOTES, 'utf-8');
}
public static function clean_json(string $json) : string {
return json_encode($json, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);
}
}
Base class:
define("LOCATION_DEFAULT_DIR", "index.php");
class Base
{
public static function location($dir = LOCATION_DEFAULT_DIR)
{
header("Location: " . $dir);
exit();
}
public static function check_input($required, $error)
{
foreach ($required as $field) {
if (empty($_POST[$field])) {
Base::location($error);
}
}
}
}