1

My models are inside the namespace App\Model. With composer auto-loading, they are only loaded when in use. But I want every class/interfaces/traits inside the App\Model to be preloaded to this script file (SchemaGenerator.php which is under App namespace) without the use of Model instances inside the class)

Similar Example:

src/Test.php:

    <?php
      namespace App;
      class Test{
         public static function run(){
           print_r(get_declared_classes());
         }
      }
       Test::run();
    ?>

Medicine.php:

    <?php
    namespace App\Model;
    class Medicine{
      // --snip--
    }

composer.json:

      "autoload": {
         "psr-4": {
                "App\\": "src/"
          }
       }
helle
  • 11,183
  • 9
  • 56
  • 83
  • 3
    _With composer auto-loading, they are only loaded when in use_ I think autoloading is different from dependency injection. – nice_dev May 30 '22 at 11:22
  • Does this answer your question? [How to get all class names inside a particular namespace?](https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace) – Justinas May 30 '22 at 12:03
  • @nice_dev what does that mean? – Sadistic Nepal May 30 '22 at 15:17
  • Can you `var_dump(get_declared_classes());` and check what all you get? – nice_dev May 30 '22 at 16:45
  • Whenever I use the class before the call, it will be included in the get_declared_classes() array – Sadistic Nepal Jun 18 '22 at 13:00
  • If I don't use any class (for eg; Test or Medicine in index.php but include_once "vendor/autoload.php" , I will only get autoloader specific classses i.e. ComposerAutoloaderIniteae55fc5ac92bded56c0e5a1c5385b62 Composer\Autoload\ClassLoader Composer\Autoload\ComposerStaticIniteae55fc5ac92bded56c0e5a1c5385b62 My question was to preinclude Medicine too without using Medicine class? – Sadistic Nepal Jun 18 '22 at 13:45

1 Answers1

0

PHP class autoloading in general and Composer implementation in particular work by crafting a file path following a set of rules (programmed in PHP code) and attempting to include such file. The whole process is triggered when PHP executes a piece of code that requires a class definition for a not yet defined class. Here's a quick and dirty implementation to illustrate that:

namespace Stack\Overflow\Example;

spl_autoload_register(function ($name) {
    echo "Trying to load class '$name'... ";
    $file = match ($name) {
        'Stack\\Overflow\\Example\\Not\\Yet\\Defined\\Class' => '/some/file.php',
        default => throw new \RuntimeException("Unknown class: $name"),
    };
    echo "Loading file '$file'\n";
    include $file;
});

$thisWrontTriggerAutload = Foo\Bar::class;
$thisWillDo = new Not\Yet\Defined\Class();

Trying to load class 'Stack\Overflow\Example\Not\Yet\Defined\Class'... Loading file '/some/file.php'

The only difference with what Composer does is that this tool implements well-known naming conventions (PSR-0 and PSR-4) to map names with files.

What you need is essentially the other way round: rather than getting a file from a class name, you need a class name from a file. There isn't a builtin functionality, neither in PHP nor in Composer, but it should be easy to do:

  1. Use file system functions to traverse the src subdirectory where you expect your entity classes to be.

  2. Include the files you find. This is safe, as long are you're careful with your conventions and your files only contain class definitions.

  3. Get the list of declared classes and filter by namespace.

For reference, this is how the Doctrine ORM library finds migration classes.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360