Quellcode durchsuchen

Refactored

Signed-off-by: Sina Kuhestani <sina@ephpic.org>
Sina Kuhestani vor 4 Tagen
Ursprung
Commit
50108af616
3 geänderte Dateien mit 196 neuen und 48 gelöschten Zeilen
  1. 16 5
      LICENSE
  2. 29 14
      autoload.php
  3. 151 29
      src/Autoloader.php

+ 16 - 5
LICENSE

@@ -1,8 +1,19 @@
-MIT License
-Copyright (c) <year> <copyright holders>
+Copyright (c) 2025-present Sina Kuhestani
 
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 29 - 14
autoload.php

@@ -1,14 +1,29 @@
-<?php
-
-/**
- * Includes the Autoloader class from the specified directory.
- *
- * This script includes the Autoloader.php file located in the "src" directory
- * relative to the current directory. This is necessary for utilizing the
- * Autoloader functionality in the application.
- *
- * @package ePHPic\Autload
- * @file Autoload.php
- */
-
-include __DIR__ . DIRECTORY_SEPARATOR . "src" . DIRECTORY_SEPARATOR . "Autoloader.php";
+<?php declare (strict_types = 1);
+
+/*******************************************************************************
+ * Front Controller
+ * *****************************************************************************
+ * This file serves as the front controller for the ePHPic Autoloader.
+ * 
+ * @package   ePHPic\Autoload
+ * @version   1.0.0
+ * @author    Sina Kuhestani <sina@ephpic.org>
+ * @license   MIT License
+ * @copyright 2025 © Sina Kuhestani
+ * @link      https://code.ephpic.org/ephpic/autoload
+ ******************************************************************************/
+
+$autoloaderFilePathArray =  [
+    __DIR__,
+    'src',
+    'Autoloader.php'
+];
+
+/* Autoloader file */
+$autoloaderFilePath = implode (
+    separator: DIRECTORY_SEPARATOR, 
+    array: $autoloaderFilePathArray
+);
+
+/* Include Autoloader file */
+require_once $autoloaderFilePath;

+ 151 - 29
src/Autoloader.php

@@ -1,23 +1,41 @@
-<?php
+<?php declare (strict_types = 1);
 
 namespace ePHPic\Autload;
 
-/**
+/*******************************************************************************
  * Class Autoloader
- *
- * A simple autoloader for loading PHP classes based on a defined mapping and base directory.
- *
- * @package ePHPic\Autload
- */
+ * *****************************************************************************
+ * A simple autoloader for loading PHP classes based on a defined mapping and 
+ * base directory.
+ * 
+ * @package   ePHPic\Autoload
+ * @author    Sina Kuhestani <sina@ephpic.org>
+ * @license   MIT License
+ * @copyright 2025 © Sina Kuhestani
+ * @link      https://code.ephpic.org/ephpic/autoload
+ ******************************************************************************/
 class Autoloader
 {
     /**
-     * @var string The base directory for the autoloader.
+     * The base directory for the application.
+     *
+     * This static property holds the absolute path to the base directory where 
+     * the application files are located. It is used for resolving paths to
+     * resources and ensuring that file operations are performed in the
+     * correct directory.
+     *
+     * @var string
      */
-    private static $baseDir = "/var/www/html";
+    private static $baseDirectory = '/var/www/html';
 
     /**
-     * @var array A mapping of class names to file paths.
+     * A mapping of class names to file paths.
+     *
+     * This static property stores an associative array that maps fully 
+     * qualified class names to their corresponding file paths. This allows for
+     * quick resolution of class locations when autoloading.
+     *
+     * @var array
      */
     private static $map = [];
 
@@ -32,20 +50,108 @@ class Autoloader
      * @param string|null $path An optional additional path to append.
      * @return string The resolved file path for the class.
      */
-    public static function resolve($class, $path = null)
+    public static function resolve (string $class, ?string $path = null): string
     {
-        if(isset(static::$map[$class]))
-        {
-            return static::$baseDir . "/" . static::$map[$class] . ($path ? "/$path" : "") . ".php";
+        /* Boolean var, indicates if the class name is present in class map */
+        $isClassInMap = key_exists (
+            key: $class, 
+            array: static::$map
+        );
+
+        /* When class name is explicitly present in the class map */
+        if (true === $isClassInMap)
+        {/* ⚠️ NOT COMMON CASE */
+            /* Use path from class map to create full path of the class file */
+            return static::buildPath($class, $path, true);
         }
-        $lastBackslashPos = strrpos($class, '\\');
-        if ($lastBackslashPos !== false) {
-            $path = substr($class, $lastBackslashPos+1, strlen($class) - 1) . ($path ? "/$path" : "");
-            $class = substr($class, 0, $lastBackslashPos);
+
+        /* Get position of last backslash in the class name */
+        $lastBackslashPos = strrpos (
+            haystack: $class, 
+            needle: '\\'
+        );
+
+        /* Boolean var, indicates if class name has backslash */
+        $hasBackSlash = false !== $lastBackslashPos;
+
+        /* When class name has backslashes */
+        if (true === $hasBackSlash)
+        { /* 🚀 COMMON CASE */
+            /* Remove last section of calss name and add to expected file path */
+            $subString = substr (
+                string: $class, 
+                offset: $lastBackslashPos+1, 
+                length: strlen ($class) - 1
+            );
+            $suffix = $path ? DIRECTORY_SEPARATOR . $path : '';
+            
+            /* This is expected path for file location */
+            $path = $subString . $suffix;
+            
+            /* This is shortened class name to resolve again */
+            $class = substr (
+                string: $class, 
+                offset: 0, 
+                length: $lastBackslashPos
+            );
+
+            /* Retry to resolve new shortened $class */
             return static::resolve($class, $path);
         }
 
-        return static::$baseDir . "/" . str_replace("\\","/",$class) . ($path ? "/$path" : "") . ".php";
+        /* Return completely expected file path */
+        return static::buildPath($class, $path, false);
+    }
+
+    /**
+     * Constructs the full file path for a given class name.
+     *
+     * This method builds the file path for the specified class based on the
+     * provided parameters. It can either use a mapping of class names to file
+     * paths or construct the path directly from the class name. The resulting
+     * path is suitable for including the class file.
+     *
+     * @param string $class The fully qualified class name for which to build 
+     * the path.
+     * @param string $path A path to append to the base path.
+     * @param bool $useMap Indicates whether to use the mapping of class names 
+     * to file paths. If true, the method will use the mapping to resolve the 
+     * file path. If false, it will construct the path based on the class name.
+     * @return string The constructed file path for the class.
+     */    
+    private static function buildPath(string $class, string $path, bool $useMap = true): string
+    {
+        /* When $useMap is true, then it uses class map to expect file path */
+        if (true === $useMap)
+        {
+            $filePathArray = [
+                static::$baseDirectory,
+                DIRECTORY_SEPARATOR,
+                static::$map[$class],
+                $path ?  DIRECTORY_SEPARATOR . $path : '',
+                '.php'
+            ];
+        }
+        /* When $useMap is false, it expects the file path following PSR-4 */
+        else
+        {
+            $filePathArray = [
+                static::$baseDirectory,
+                DIRECTORY_SEPARATOR,
+                str_replace ('\\', DIRECTORY_SEPARATOR, $class),
+                $path ? DIRECTORY_SEPARATOR . $path : '',
+                '.php'
+            ];
+        }
+        
+        /* Merge filePath segments and create full path */
+        $filePath = implode (
+            separator: '',
+            array: $filePathArray
+        );
+
+        /* Return the expected class file path */
+        return $filePath;
     }
 
     /**
@@ -56,12 +162,23 @@ class Autoloader
      * @param string $class The fully qualified class name to autoload.
      * @return void
      */
-    public static function autoload($class)
+    public static function autoload ($class): void
     {
-        $filePath = static::resolve($class);
-        if(@file_exists($filePath))
+        /* Get expected class file */
+        $filePath = static::resolve (
+            class: $class,
+            path: null
+        );
+
+        /* Boolean var, indicates if class file exists */
+        $fileExists = @file_exists (
+            filename: $filePath
+        );
+
+        /* When class file exists simply include it */
+        if (true === $fileExists)
         {
-            include_once $filePath;
+            require_once $filePath;
         }
     }
 
@@ -71,16 +188,21 @@ class Autoloader
      * This method allows the autoloader to be registered so that it can be used
      * to automatically load classes when they are referenced.
      *
-     * @param string $baseDir The base directory for the autoloader.
+     * @param string $baseDirectory The base directory for the autoloader.
      * @param array $map An associative array mapping class names to file paths.
      * @return void
      */
-    public static function register($baseDir, $map)
+    public static function register ($baseDirectory, $map): void
     {
-        spl_autoload_register(
-            [static::class, "autoload"], 
-            true, 
-            true
+        /* Initialize Autoloader class map and base directory */
+        static::$baseDirectory = $baseDirectory;
+        static::$map = $map;
+
+        /* Register the method autoload as php autoloader */
+        spl_autoload_register (
+            callback: [static::class, 'autoload'], 
+            throw: true, 
+            prepend: true
         );
     }
 }