Search code examples
phpapacheframeworksphp-8

PHP for loop not accessing variable passed in params but accessible outside for loop


<?php 
class App {
    function __construct($settings) {
        /*if(isset($settings->preload)) {
            die('yes');
        } else {
            die('no');
        }*/
        for ($i = 0; $i <= sizeof($settings->preload); $i++) {
            spl_autoload_register(function($class_name) {
                if(file_exists($settings->preload[$i].$class_name.'.php'))
                    require_once ''.$settings->preload[$i].$class_name.'.php';
            });
        }
    }
}
?>

Hello, I am writing my own php specific framework as other frameworks just can't do the job I want done,

This is a behemoth of a task I have decided to change my "Routing System" which has entailed me to preload selected classes that are dragged in from the $settings param. I'm passing a "Settings" class into my class constructor param, which is being accessed, I have checked the array count and also checked if it isset which it is, however once it goes into the for loop it is null

Warning: Undefined variable $settings in /***/*****/****/PHPFRAMEWORK/System/App.php on line 6

The for loop is just to preload classes that are added into the Settings class.

My Question is

  • What is wrong with this code?
  • Is this a PHP specific problem?

Solution

  • You are not taking into account the scope of the variables within a function.

    If you want "settings" available inside the nested function you need to pass it as a parameter:

    Inside your for loop, if you want settings to be available, you need to pass $settings as a parameter to the anonymous function you are introducing into spl_autoload_register:

                spl_autoload_register(function($class_name`, $settings) {
                    if(file_exists($settings->preload[$i].$class_name.'.php'))
                        require_once ''.$settings->preload[$i].$class_name.'.php';
                });
            
    

    PS: The first time I tried to build my own Autoloader I built something similar. I don't want to tell you not to try to build your own, but I do recommend you to look into namespaces and PSR-4 autoloading.