# Autoload new PHP Class in Sage 10

**URL:** https://discourse.roots.io/t/autoload-new-php-class-in-sage-10/24892
**Category:** sage
**Tags:** composer, sage10
**Created:** 2023-03-02T17:25:36Z
**Posts:** 6

## Post 1 by @SnazzyCreative — 2023-03-02T17:25:36Z

Hey there,

Long time Sage builder here finally making the switch to version 10. I’m trying to upgrade my approach by utilizing the autoloader feature after seeing it in play on some recent non-sage projects.

I believe I am following the PSR-4 namespace, as shown in the below screenshot, but the file doesn’t seem to be loading. I don’t fully understand how PHP classes work but what I’m working with is loosley based on the previous project I mentioned. Trying to echo out test data into the `wp_footer` hook isn’t producing anything either.

I have also run `composer dump-autoload` and the class count does include my new `Event` class.

 ![Screenshot 2023-03-02 at 17.18.30](https://discourse.roots.io/uploads/default/original/2X/c/cbea032f5da5aa4e368d65c11cfcbf5355665efd.png)

file path: `app/PostTypes/Event.php`

```
<?php

Namespace App\PostTypes;

class Event
{
    private $slug = 'event';

    private $options = [
        'rewrite' => false,
        'public' => false,
    ];

    public function __construct()
    {
        add_action('init', [$this, 'register']);
    }

    public function register()
    {
        register_extended_post_type( $this->slug, $this->options );
    }
}
```

I’m not sure where to go from here. Any help would be appreciated. Thanks!

---

## Post 2 by @EHLOVader — 2023-03-02T18:33:51Z

If you were having a hard time calling that class from other files by name.

I believe what you are experiencing is case sensitivity… `app` vs `App` although that could be handled safely in the composer.json it is best to match case.

Case sensitivity issues will also present themselves differently on some systems, as some systems (like local envs) aren’t case sensitive but most production servers you will be using are.

---

## Post 3 by @SnazzyCreative — 2023-03-02T19:05:40Z

I’m running pretty close to an unchanged Sage 10. The `app` namespace is lowercase in `composer.json` and everywhere else in the theme. I have matched the case everywhere else in the path.

![Screenshot 2023-03-02 at 19.03.19](https://discourse.roots.io/uploads/default/original/2X/f/f6dd32ade7c6ff01f7c4fe2fce080ca6e91a9c0f.png)

```
"autoload": {
    "psr-4": {
      "App\\": "app/"
    }
  },
```

---

## Post 4 by @talss89 — 2023-03-02T19:09:32Z

LGTM @SnazzyCreative! That seems like it should work.

How are you calling the constructor?

Apologies if you are aware of the following, but since you mention you’re new to classes, this may help:

Although composer will load PSR-4 classes, the code in your constructor - `public function __construct() {}` - will never run, unless you create an _instance_ of the _class_. This can be done simply: `$post_type_event = new \App\Event\PostType();`

The `new` operator will call your `__construct()` method for you.

Alternatively, as registering a post type is a generally only done once, you could use a _static method_, and call that via `add_action('init', ['\App\PostTypes\Event', 'my_static_register_method'])`. There is no need to create an instance if calling a _static method_, but remember `$this` is not available - use `self::` to access static properties.

* * *

PS. If you could use backticks and code instead of screenshots that would be great - makes the thread much more accessible.

---

## Post 5 by @SnazzyCreative — 2023-03-03T12:07:48Z

Thanks @talss89!

I am not calling the constructor so that explains why this code isn’t running. I missed this from the project I’m basing this on. There would be a line for each class in one of the base files.

`use App\PostTypes\Event;` (full namespace path / class name)

This feels like it goes against the autoloading approach if each file has to be declared anyway. I’m basically looking to re-create the simplicity of `soberwp/models` on Sage 9 using `johnbillion/extended-cpts`, with a separate file for each custom post type.

My old approach would be to make a separate file for each post type and loop through them to `require_once` each file.

```
register_extended_post_type( $postType, $options );
```

I’m trying to modernise and the composer autoloading only triggering when needed sounds like the right way to go. I also don’t want to be needlessly complicated.

---

## Post 6 by @talss89 — 2023-03-03T12:55:34Z

Ah, understood! PSR-4 autoloading may not be the solution you’re looking for, although it’s a great standard to adhere to anyway for maintainability.

Here’s a function I’ve quickly put together which will instantiate all classes and fire constructors in your `App/PostTypes` namespace. If keeping a reference to your instance is important, you may want to modify, as the instance `new $class()` is just left on the stack.

```
function load_all_post_types($ns = 'App\PostTypes') {
    foreach(glob( __dir__. '/PostTypes/*.php') as $fn) {
        $class = $ns . '\\' . basename($fn, '.php');
        new $class();
    }
}
```

_This assumes you’re calling this function from your `./app` dir. If not, modify the `glob()` call. Also, please bear in mind this isn’t tested production code - globbing on each request isn’t performant, and there may be other issues._

For a bit of background; Composer autoloading works by registering an autoload handler (`spl_autoload_register()`) which is only fired if a class name is referenced, but cannot be found. It’s almost like a final error handler before throwing an exception. That’s why just adding files to the directory won’t execute any code without a reference to it.
