34

Here is my folder structure:

Classes
  - CronJobs
    - Weather
      - WeatherSite.php

I want to load WeatherSite class from my script. Im using composer with autoload:

$loader = include(LIBRARY .'autoload.php');
$loader->add('Classes\Weather',CLASSES .'cronjobs/weather');
$weather = new Classes\Weather\WeatherSite();

Im assuming the above code is adding the namespace and the path that namespace resolves to. But when the page loads I always get this error:

 Fatal error: Class 'Classes\Weather\WeatherSite' not found

Here is my WeatherSite.php file:

namespace Classes\Weather;

class WeatherSite {

    public function __construct()
    {

    }

    public function findWeatherSites()
    {

    }

}

What am I doing wrong?

John
  • 9,840
  • 26
  • 91
  • 137
  • You actually don't need custom autoloader, you probably can use PSR-4. Do you use `composer.json`? If so, could you add it's content in `autoload` section? – Tomas Votruba Jul 19 '15 at 19:20
  • @Tomáš Votruba I thought for custom classes I write I would have to add the namespaces to the autoloader script that comes with composer? – John Jul 19 '15 at 19:22

1 Answers1

65

You actually don't need custom autoloader, you can use PSR-4.

Update your autoload section in composer.json:

"autoload": {
    "psr-4": {
        "Classes\\Weather\\": "Classes/CronJobs/Weather"
    }
}

To explain: it's {"Namespace\\\": "directory to be found in"}

Don't forget to run composer dump-autoload to update Composer cache.

Then you can use it like this:

include(LIBRARY .'autoload.php');

$weather = new Classes\Weather\WeatherSite();
Tomas Votruba
  • 23,240
  • 9
  • 79
  • 115
  • Thank you, but how do I reference the name space in the script then? Do I still need to add Namespace Classes to the top of my custom class file, WeatherSite.php? And in the script that calls the class is it just $site_weather = new Classes\Weather\SiteWeather()? – John Jul 19 '15 at 19:25
  • Nevermind, I got it to work, but only if the namespace in composer points to the sub directory that the php file is in. So if composer I have it Classes => class/CronJobs then in the script $weather = new Classes\Weather\WeatherSite(); I still get the error, but if I update composer to Classes => class/CronJobs/Weather it now works. Any idea what Im still doing wrong? – John Jul 19 '15 at 19:40
  • Ok looks like I figured that out. In the WeatherSite.php file I changed it from namespace Classes to namespace Classes\Weather and now it works. Thank you for all your help. Can you confirm this is the correct way of doing something like this? Or is this a bad "design"? – John Jul 19 '15 at 19:44
  • Sorry, I've fixed my answer accordingly. Have you tried the `composer.json` way? That's the correct one. Using `$loader` is bad practice. – Tomas Votruba Jul 19 '15 at 19:56
  • What I did was in composer I added the root directory of my class folder instead of the cronjob sub folder. Then in the script I just use that namespace to drill down to the class I need. So in WeatherSite.php at the top I now have namespace Classes\CronJobs\Weather; and then in the script to call it I have $weather = new Classes\CronJobs\Weather\WeatherSite(); Im hoping this is the correct way moving forward. Still learning about composer/autoload/namespaces – John Jul 19 '15 at 20:00
  • This might be useful source for you: http://www.sitepoint.com/battle-autoloaders-psr-0-vs-psr-4/ - check ONLY PSR-4 section, because PSR-0 is deprecated since Autumn 2014. – Tomas Votruba Jul 19 '15 at 20:02
  • 1
    'composer dump-autoload' doesnt work for me but 'php artisan optimize' work for me . – mmw5610 Sep 28 '16 at 00:38