Skip to content

Commit 6837df3

Browse files
derrabusfabpot
authored andcommitted
[ClassLoader] A PSR-4 compatible class loader
1 parent 4ad343b commit 6837df3

File tree

6 files changed

+193
-0
lines changed

6 files changed

+193
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ClassLoader;
13+
14+
/**
15+
* A PSR-4 compatible class loader.
16+
*
17+
* See http://www.php-fig.org/psr/psr-4/
18+
*
19+
* @author Alexander M. Turek <me@derrabus.de>
20+
*/
21+
class Psr4ClassLoader
22+
{
23+
/**
24+
* @var array
25+
*/
26+
private $prefixes = array();
27+
28+
/**
29+
* @param string $prefix
30+
* @param string $baseDir
31+
*/
32+
public function addPrefix($prefix, $baseDir)
33+
{
34+
$prefix = trim($prefix, '\\').'\\';
35+
$baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
36+
$this->prefixes[] = array($prefix, $baseDir);
37+
}
38+
39+
/**
40+
* @param string $class
41+
*
42+
* @return string|null
43+
*/
44+
public function findFile($class)
45+
{
46+
$class = ltrim($class, '\\');
47+
48+
foreach ($this->prefixes as $current) {
49+
list($currentPrefix, $currentBaseDir) = $current;
50+
if (0 === strpos($class, $currentPrefix)) {
51+
$classWithoutPrefix = substr($class, strlen($currentPrefix));
52+
$file = $currentBaseDir . str_replace('\\', DIRECTORY_SEPARATOR, $classWithoutPrefix) . '.php';
53+
if (file_exists($file)) {
54+
return $file;
55+
}
56+
}
57+
}
58+
}
59+
60+
/**
61+
* @param string $class
62+
*
63+
* @return Boolean
64+
*/
65+
public function loadClass($class)
66+
{
67+
$file = $this->findFile($class);
68+
if (null !== $file) {
69+
require $file;
70+
71+
return true;
72+
}
73+
74+
return false;
75+
}
76+
77+
/**
78+
* Registers this instance as an autoloader.
79+
*
80+
* @param Boolean $prepend
81+
*/
82+
public function register($prepend = false)
83+
{
84+
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
85+
}
86+
87+
/**
88+
* Removes this instance from the registered autoloaders.
89+
*/
90+
public function unregister()
91+
{
92+
spl_autoload_unregister(array($this, 'loadClass'));
93+
}
94+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Acme\DemoLib;
4+
5+
class Class_With_Underscores
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Acme\DemoLib;
4+
5+
class Foo
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Acme\DemoLib\Lets\Go\Deeper;
4+
5+
class Class_With_Underscores
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Acme\DemoLib\Lets\Go\Deeper;
4+
5+
class Foo
6+
{
7+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ClassLoader\Tests;
13+
14+
use Symfony\Component\ClassLoader\Psr4ClassLoader;
15+
16+
class Psr4ClassLoaderTest extends \PHPUnit_Framework_TestCase
17+
{
18+
/**
19+
* @param string $className
20+
* @dataProvider getLoadClassTests
21+
*/
22+
public function testLoadClass($className)
23+
{
24+
$loader = new Psr4ClassLoader();
25+
$loader->addPrefix(
26+
'Acme\\DemoLib',
27+
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'psr-4'
28+
);
29+
$loader->loadClass($className);
30+
$this->assertTrue(class_exists($className), sprintf('loadClass() should load %s', $className));
31+
}
32+
33+
/**
34+
* @return array
35+
*/
36+
public function getLoadClassTests()
37+
{
38+
return array(
39+
array('Acme\\DemoLib\\Foo'),
40+
array('Acme\\DemoLib\\Class_With_Underscores'),
41+
array('Acme\\DemoLib\\Lets\\Go\\Deeper\\Foo'),
42+
array('Acme\\DemoLib\\Lets\\Go\\Deeper\\Class_With_Underscores')
43+
);
44+
}
45+
46+
/**
47+
* @param string $className
48+
* @dataProvider getLoadNonexistentClassTests
49+
*/
50+
public function testLoadNonexistentClass($className)
51+
{
52+
$loader = new Psr4ClassLoader();
53+
$loader->addPrefix(
54+
'Acme\\DemoLib',
55+
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'psr-4'
56+
);
57+
$loader->loadClass($className);
58+
$this->assertFalse(class_exists($className), sprintf('loadClass() should not load %s', $className));
59+
}
60+
61+
/**
62+
* @return array
63+
*/
64+
public function getLoadNonexistentClassTests()
65+
{
66+
return array(
67+
array('Acme\\DemoLib\\I_Do_Not_Exist'),
68+
array('UnknownVendor\\SomeLib\\I_Do_Not_Exist')
69+
);
70+
}
71+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy