php – Review of Design, code, structure, pattern in project with poor reception

Question:

For some time I have been developing on a platform that although it is functional, they leave me negative comments and opinions about the Architecture / Structure / design pattern / anti design pattern, because it is outdated, I have not even been able to find which pattern they used.

I have researched in depth and both composer and other frameworks use class loaders.

These loaders some use spl_autoload_####### , in their architecture; with the idea that the developer uses namespaces or class instances like:

<?php
class Foo {
    public $aMemberVar = 'aMemberVar Member Variable';
    public $aFuncName = 'aMemberFunc';
   
   
    function aMemberFunc() {
        print 'Inside `aMemberFunc()`';
    }
}

$foo = new Foo;
?>

for later:

<?php
$element = 'aMemberVar';
print $foo->$element; // prints "aMemberVar Member Variable"
?>

the Autoload criterion of the Composer or framewrok is in charge of making the include_once or require_once , spl_autoload_####### of the necessary file where the class or function is found; this also allows you to run standalone PHP files as long as you have the USE NAMESPACE/NAMESPACE .

spl_autoload_register(function ($clase) {
    include 'clases/' . $clase . '.clase.php';
});

The

namespace Foobar;

class Foo {
    static public function test($nombre) {
        print '[['. $nombre .']]';
    }
}

spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // A partir de PHP 5.3.0

new ClaseInexistente;

Error

[[Foobar \ MissingClass]] Fatal error: Class 'Foobar \ MissingClass' not found in …

So, in the code I'm working on they do something completely different:

The file index.php that acquires a whining of the system using a requiere_once also have a parent class CoreApp is always the one that receives all initial access requests: GET, POST, etc.

<?php
//require_once 'configs/const/loader.php'; // Acceso a las constantes del sistema
//se agrego las definiciones para hacer que el codigo sea ejecutable.
if (!defined('FILEROOT')) {
    define('FILEROOT', $_SERVER['DOCUMENT_ROOT']);
}
$paths = [
    'CLASSEXT'  => FILEROOT.'/apps/class/ext/',
    'CLASSMVC'  => FILEROOT.'/apps/class/mvc/',
    'CLASSGEN'  => FILEROOT.'/apps/class/gen/',
    'CLASSCORE' => FILEROOT.'/apps/core/',
    'TPLSTATIC' => FILEROOT.'/html/static/',
    'TPLDASH'   => FILEROOT.'/html/dash/',
    'TPLSITE'   => FILEROOT.'/html/site/',
    'TPLSTATUS' => FILEROOT.'/html/status/',
    'TPLSTORE'  => FILEROOT.'/html/store/'
];
if (!defined('PATHS')) {
    define('PATHS', $paths);
}

class CoreApp
{
    public static $oclass = null;

    // propiedad de la clase en donde se Guardaran las clases que se heredaran en las sub-capas

    public static $ovars = null;

    //  propiedad de la clase en donde se Guardaran las variables que se heredaran en las sub-capas

    private static $instance = null;

    public static function _getInstance()
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function goCoreApp()
    {
        $this->popClass();
        echo 'hello World';
        //self::$oclass['GEN']['APP']->runInit();
        //self::$oclass['MVC']['CONTROLLER']->runController();
        //self::$oclass['GEN']['APP']->runClose();

    }

    private function popClass()
    {
        //se llama al archivo y la funcion que se encargara de poblar la porpiedad $oclass
        require_once FILEROOT.'/apps/class-manager.php';
        ClassManager::_getInstance()->LoadClass();
    }
}
ob_start();
CoreApp::_getInstance()->goCoreApp();

Then in the next layer call ClassManager::_getInstance()->LoadClass(); which is a class loader which will populate the CoreApp::$oclass that is executed as follows:

<?php
class ClassManager
{
    private static $instance = null;

    public function LoadClass()
    {
        $classPaths = [
            'GEN' => PATHS['CLASSGEN'],
            'MVC' => PATHS['CLASSMVC']
        ];
        $this->requireClassFile(PATHS['CLASSEXT'].'vendor/autoload.php');
        $this->ClassLoader($classPaths);
    }

    public static function _getInstance()
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    private function CheckFileIntegrity($file)
    {
        $dl    = ['st' => false, 'msg' => ''];
        $smg1  = '';
        $fileR = file($file);
        $c     = 1;
        foreach ($fileR as $line) {
            if (!strlen(trim($line))) {
                $smg1 .= 'Incorrect space/Linebreak found file: '.$file.EOL_SYS.'Line: '.$c.EOL_SYS;
                $dl['st'] = true;
                ++$c;
            } else {
                break;
            }
        }
        $dl['msg'] = $smg1;
        return $dl;
    }

    private function ClassLoader($classPaths)
    {
        foreach ($classPaths as $key => $path) {
            $dl          = [];
            $class_store = &CoreApp::$oclass[$key];
            $files       = array_diff(
                scandir($path, 1),
                ['..', '.']
            );
            foreach ($files as $key => $name) {
                if (strpos($name, 'class-') !== false) {
                    $fl_dir = $path.$name;
                    $dl     = $this->CheckFileIntegrity($fl_dir);
                    if (!$dl['st']) {
                        $this->requireClassFile($fl_dir);
                        $name = explode("-", preg_replace('#\.php#', '', $name));
                        foreach ($name as $key => $cl_name) {
                            $name[$key] = ucfirst(strtolower($cl_name));
                        }
                        $new_name_class = implode('', $name);
                        $instance_class = strtoupper(
                            preg_replace('#\Class#', '', $new_name_class)
                        );
                        $new_name_class .= 'Manager';
                        $class_store[$instance_class] = $new_name_class::_getInstance();
                    } else {
                        echo
                            'PHP files cannot have line breaks at the beginning '.
                            'or end.<br> There is a problem with this file: <b> '.
                            PATHS['CLASSGEN'].$name.'</b> <br> <br>'.
                            $dl['msg'];
                        die;
                    }
                }
            }
        }
    }

    private function requireClassFile($file)
    {
        return require_once $file;
    }
}

Dependency: For this Script to work, it is necessary to create a folder in root with the following structure:

/apps/class/ext/ #where the entire composer installation and external libraries accessible by composer autoload will be placed.

/apps/class/gen/ #where all generic classes will be placed.

/apps/class/mvc/ #where all mvc classes will be placed.

Example of a Generic Class and an MVC:

class-test.php // class name must start with class-

class ClassTestManager
{
    private static $instance = null;
    
    public static function _getInstance()
    {
    
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        return self::$instance;
    }
    public function test()
    {
        echo 'hello world';
    }
}

In summary:

for the end they have the property CoreApp::$oclass with all the classes pre-installed. Once this is done from any layer, a function can be called in the following way:


self::$oclass['GEN']['TEST']->test();

self::$oclass['GEN']['APP']->runInit();
self::$oclass['MVC']['CONTROLLER']->runController();
self::$oclass['GEN']['APP']->runClose();

The

CoreApp::$oclass['GEN']['VARS']->expVariable(true, true, false, true, CoreApp::$ovars, [$stuser, $isdata, $isdatatype, $iscron, $iswser])

it does not require the use of USE NAMESPACE/NAMESPACE or the use of Instancias ; neither to extender .

But I have never had a canonical answer as to why?
Project Link on Github
this is a project with little documentation in the code, Questions:

  1. What pattern is it?
  2. What are the weaknesses of this Architecture / Structure / design pattern / anti design pattern or the logic of using an Object or property to inherit pre-initialized Classes and Functions?
  3. What Errors can I be committing, that the application stops working or is it an exploit?
  4. What improvements (re-factory) can the code of the class ClassManager to make it more efficient?

Update Comments / Clarifications

  1. They indicate that a weakness to pre-initialize classes that are not used because they read from disk and save data in ram memory and can impact the speed of the system, for example knowing the server time for any use within the system.

Answer: The truth is that it is only read from disk once, and it is also saved once in ram, and the resource is saved in the object / Property CoreApp::$oclass which provides access in RAM at CoreApp::$oclass to any Class / function without resorting to SPL_AUTOLo- … Is or is not a Weakness; you will need to test true scalability.

Answer:

  1. What pattern is it?

Answer: it is not a definite pattern; what is implemented is an "orthodox" pattern from the days when namespaces did not exist yet and it is a mix between factory, construction and Singleton. It is not badly planned, it is manageable but not the best option, among the existing ones (canonically, this pattern does not even have a record).

  1. What are the weaknesses of this Architecture / Structure / design pattern / anti design pattern or the logic of using an Object or property to inherit pre-initialized Classes and Functions?

Answer: the only Appreciable Weakness is; its limitations mainly with the software traceability of the code since the Symbolic Methods have these problems and an indexing by text search must be used, this is present only in ST3; but VScode and phpStorm don't have proper / native support.

Example:

self::$oclass['MVC']['CONTROLLER']->runController();

Current editors do not have the ability to trace the path to the runController function because it is nesting symbolically in an Array that was not declared; otherwise it was built in real time.

  1. What Errors can I be committing, that the application stops working or is it an exploit?

Answer: As I said at the beginning, the only exploit that it may have depends on the version of php and the errors made by the programmer … there are no Exploits if a security layer is correctly presented.

  1. What improvements (re-factory) can the code of the class ClassManager to make it more efficient?

Answer: normally All projects with these characteristics tend to migrate to design patterns that employ the use of namespace and resource control based on a logic established in common among developers since it does not respond to any development framework structure.

Currently the Development is being refactored and migrated to this last point mentioned.

Scroll to Top