Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2a15923

Browse files
committed
feature #10100 [ClassLoader] A PSR-4 compatible class loader (derrabus)
This PR was squashed before being merged into the 2.5-dev branch (closes #10100). Discussion ---------- [ClassLoader] A PSR-4 compatible class loader | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | This is a PSR-4 compatible class loader that I'd like to contribute to the ClassLoader component. Since PSR-4 is the most recent FIG standard for an autoloader, I thought a compatible loader should be part of a feature-complete ClassLoader component. See: http://www.php-fig.org/psr/psr-4/ PSR-4 does neither replace PSR-0, nor are those standards 100% compatible. This is why I implemented the standard as a new class. If you decide that my PR is worth merging, I would also provide a PR for symfony-docs with a documentation. Commits ------- 6837df3 [ClassLoader] A PSR-4 compatible class loader
2 parents 725f7ab + 6837df3 commit 2a15923

File tree

6 files changed

+193
-0
lines changed

6 files changed

+193
-0
lines changed
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 <[email protected]>
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 <[email protected]>
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+
}
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+
}
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+
}
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+
}
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+
}
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 <[email protected]>
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)