2

First off, I'm trying my hand using the following SplClassLoader -https://gist.github.com/221634

Here is my file structure:

/root/f1/f2/APS/Common/Group.php
/root/f1/f2/index.php
/root/f1/f2/SplClassLoader.php

Here is my test class called Group (Group.php)

namespace APS\Common;

class Group{
...
}

Here is the index.php file that is calling everything:

require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS', 'APS/Common');
$classLoader->register();

I'm getting the following error:

Fatal error: Class 'Group' not found in /root/f1/f2/index.php on line 17

I've tried every conceivable combination when passing the namespace and path to the loader. It never works.

Update #1 - Line 17 in index.php:

16: use APS\Common;
17: $x = new Group();

Update #2 - Configuration info

  • Apache/2.2.15 (Red Hat)
  • PHP 5.3.3

Update #3 - I'm getting a different error message now.

The code in place:

require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS', '/root/f1/f2');
$classLoader->register();

use APS\Common;
$x = new Common\Group();

Error message that I'm getting:

Warning: require(/f1/f2/APS/Common/Group.php): failed to open stream: No such file or directory in /root/f1/f2/SplClassLoader.php on line 133 
TechFanDan
  • 3,329
  • 6
  • 46
  • 89
  • Would it be possible to see line 17 of index.php? Are you using any 'use' statements within index.php? – David Hamp Jan 29 '13 at 20:37
  • @DavidHamp see update to my original question. I have a use statement right above my call to instantiate my class. – TechFanDan Jan 29 '13 at 20:42
  • Have you tried specifying a more explicit include path in your SplClassLoader instantiation? ('/root/f1/f2/APS/Common') – David Hamp Jan 29 '13 at 20:54
  • @DavidHamp No, I haven't... so it would look something like this new SplClassLoader('APS\Common', '/f1/f2/APS/Common') ? – TechFanDan Jan 29 '13 at 21:11

2 Answers2

0

When using the use statement (no pun intended), you simply create an alias for the used namespace or class. According to the PHP manual, use \Foo\Bar; is equivalent to use \Foo\Bar as Bar;.

So, in your case, you import the APS\Common namespace with the alias Common. This means that you can refer to the Group class within this namespace as Common\Group instead of APS\Common\Group. Without using the namespace alias (as you did), the classloader will expect the Group class to be in the global namespace (and expect the class to be stored in /root/f1/f2/Group.php).

Edit: Another possibility would be to simply put namespace \APS\Common; into your file. If you reference a class without a namespace specification (i.e. Group instead of \Group or \APS\Common), PHP will expect the class to be in the current namespace.

helmbert
  • 35,797
  • 13
  • 82
  • 95
  • I thought the namespace had to reflect the directory structure? If I put a namespace into my index.php file, then, couldn't it be confusing if I want to instantiate classes outside that package. Strangely enough, this is very confusing. – TechFanDan Jan 30 '13 at 12:16
  • True. Best reference the namespace directly, either by alias or full name (i.e. `Common\Group` or `\APS\Common\Group`). – helmbert Jan 30 '13 at 12:50
  • was this in reference to Update #4 on my original post? – TechFanDan Jan 30 '13 at 13:43
0

In my case, here is the solution that seems to work.

require "SplClassLoader.php";
$classLoader = new SplClassLoader('APS\Common', __DIR__);
$classLoader->register();

use APS\Common;
$x = new Common\Group();

I had to use the magic constant DIR for it to work. The second parameter seems to need to point to the physical path of the root of where the classes reside. Then, the namespace gets added to locate them in the file system.

TechFanDan
  • 3,329
  • 6
  • 46
  • 89