Using box/spout 3rd party library in Yii application command - php

I want to use https://github.com/box/spout library in my Yii project (in one of commands). I'm not using Composer, so I simple downloaded the extension and put in extensions/spout/Box/.
In my config/main.php I've added line
'import' => array(
...
'application.extensions.spout.*'
),
And in my command I've added following lines:
require_once Yii::app()->basePath . '/extensions/spout/Box/Spout/Reader/ReaderFactory.php';
require_once Yii::app()->basePath . '/extensions/spout/Box/Spout/Common/Type.php';
When I'm calling $reader = ReaderFactory::create(Type::CSV); I'm getting following error:
PHP Error[2]: include(ReaderFactory.php): failed to open stream: No such file or directory
in file /srv/yii/YiiBase.php at line 421
#0 /srv/yii/YiiBase.php(421): autoload()
#1 unknown(0): autoload()
#2 /srv/dev/protected/commands/AmazonCommand.php(193): spl_autoload_call()
#3 unknown(0): AmazonCommand->actionIndex()
#4 /srv/yii/console/CConsoleCommand.php(172): ReflectionMethod->invokeArgs()
#5 /srv/yii/console/CConsoleCommandRunner.php(67): AmazonCommand->run()
#6 /srv/yii/console/CConsoleApplication.php(91): CConsoleCommandRunner->run()
#7 /srv/yii/base/CApplication.php(169): CConsoleApplication->processRequest()
#8 /srv/yii/yiic.php(33): CConsoleApplication->run()
#9 /srv/dev/protected/yiic.php(19): require_once()
#10 /srv/dev/protected/yiic(4): require_once()
What I'm missing? How can I use third party library in my project?
UPDATE
After that tutorial, I've moved spout folder in protected/vendors folder and changed the code following way:
Yii::import('application.vendors.spout.Box.Spout.Reader.*');
Yii::import('application.vendors.spout.Box.Spout.Common.*');
require_once 'ReaderFactory.php';
require_once 'Type.php';
Now I'm getting following error, still no clue why:
PHP Fatal error: Cannot redeclare class Box\Spout\Reader\ReaderFactory in /srv/dev/protected/vendors/spout/B
ox/Spout/Reader/ReaderFactory.php on line 17

If you are using Yii 2.0 and since Spout is PSR4 compliant, you can follow this guide: http://www.yiiframework.com/doc-2.0/guide-structure-extensions.html#installing-extensions-manually
If you are still using Yii 1.1, I am not sure what the best way to autoload your classes is. But you can still use a standard PSR4 autoloader:
Psr4Autoloader.php
namespace Autoloader;
class Psr4Autoloader
{
/**
* An associative array where the key is a namespace prefix and the value
* is an array of base directories for classes in that namespace.
*
* #var array
*/
protected $prefixes = array();
/**
* Register loader with SPL autoloader stack.
*
* #return void
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'));
}
/**
* Adds a base directory for a namespace prefix.
*
* #param string $prefix The namespace prefix.
* #param string $base_dir A base directory for class files in the
* namespace.
* #param bool $prepend If true, prepend the base directory to the stack
* instead of appending it; this causes it to be searched first rather
* than last.
* #return void
*/
public function addNamespace($prefix, $base_dir, $prepend = false)
{
// normalize namespace prefix
$prefix = trim($prefix, '\\') . '\\';
// normalize the base directory with a trailing separator
$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
// initialize the namespace prefix array
if (isset($this->prefixes[$prefix]) === false) {
$this->prefixes[$prefix] = array();
}
// retain the base directory for the namespace prefix
if ($prepend) {
array_unshift($this->prefixes[$prefix], $base_dir);
} else {
array_push($this->prefixes[$prefix], $base_dir);
}
}
/**
* Loads the class file for a given class name.
*
* #param string $class The fully-qualified class name.
* #return mixed The mapped file name on success, or boolean false on
* failure.
*/
public function loadClass($class)
{
// the current namespace prefix
$prefix = $class;
// work backwards through the namespace names of the fully-qualified
// class name to find a mapped file name
while (false !== $pos = strrpos($prefix, '\\')) {
// retain the trailing namespace separator in the prefix
$prefix = substr($class, 0, $pos + 1);
// the rest is the relative class name
$relative_class = substr($class, $pos + 1);
// try to load a mapped file for the prefix and relative class
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
if ($mapped_file) {
return $mapped_file;
}
// remove the trailing namespace separator for the next iteration
// of strrpos()
$prefix = rtrim($prefix, '\\');
}
// never found a mapped file
return false;
}
/**
* Load the mapped file for a namespace prefix and relative class.
*
* #param string $prefix The namespace prefix.
* #param string $relative_class The relative class name.
* #return mixed Boolean false if no mapped file can be loaded, or the
* name of the mapped file that was loaded.
*/
protected function loadMappedFile($prefix, $relative_class)
{
// are there any base directories for this namespace prefix?
if (isset($this->prefixes[$prefix]) === false) {
return false;
}
// look through base directories for this namespace prefix
foreach ($this->prefixes[$prefix] as $base_dir) {
// replace the namespace prefix with the base directory,
// replace namespace separators with directory separators
// in the relative class name, append with .php
$file = $base_dir
. str_replace('\\', '/', $relative_class)
. '.php';
// if the mapped file exists, require it
if ($this->requireFile($file)) {
// yes, we're done
return $file;
}
}
// never found it
return false;
}
/**
* If a file exists, require it from the file system.
*
* #param string $file The file to require.
* #return bool True if the file exists, false if not.
*/
protected function requireFile($file)
{
if (file_exists($file)) {
require $file;
return true;
}
return false;
}
}
Then add this code to your root file or wherever you think it's the most appropriate (just make sure the path for "require_once" is correct):
autoload.php
require_once "Psr4Autoloader.php";
$loader = new \Autoloader\Psr4Autoloader;
$loader->register();
$loader->addNamespace('Box\Spout', 'vendor/box/spout/src/Spout');
You should now be able to use Spout!

Related

Loading files without instantiable classes with autoloader

This is the structure of my project:
- project
-- src
--- class1.php
--- class2.php
--- class3.php
--- class4.php
--- class.php
- autoload.php
This is how my autoloader (autoload.php) looks:
<?php
/**
* #param string $class The fully-qualified class name.
* #return void
*/
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'ProjectName';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/src/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});
Now, I have a file (class.php) which contains all configuration parameters for the rest of files located in src directory (constants, interface, abstract classes and some global functions). What's the best way to load it without interrupting whole process?

PHPUnit autoloading classes

Question in short
How can I make the Autoloader find all classes required to run my PHP tests?
Question in detail
I want to autoload the classes that I am using in PHPUnit in Eclipse. My directory structure is as follows.
Project (called yii-app)
protected
dirA
classA.php
dirB
classB.php
yii-1.1.14.f0fee9
Yii.php
tests
ClassATest.php
ClassBTest.php
bootstrap.php
Autoloader.php
I use the bootstrap.php and Autoloader.php that I found here, see below for details. The Class classA does not make use of the Yii framework, and the tests in ClassATest run smoothly. The Class classB does make use of the Yii framework. One of the first lines is:
Yii::import('application.<path into some directory>.*')
When I try to run the tests in ClassBTest.php, I get the following error.
Fatal error: Class 'Yii' not found in /Users/physicalattraction/git/yii-app/protected/dirB/classB.php on line 3
Even if I register the entire project directory (including subdirectories), Class Yii is not found, while it is right there. What should I change to make these tests run as well?
Note
I have the same problem if I try to run the tests directly from the terminal, so it is not Eclipse related.
$ ./composer/vendor/bin/phpunit --bootstrap=tests/bootstrap.php tests
PHPUnit 4.5.1 by Sebastian Bergmann and contributors.
Fatal error: Class 'Yii' not found in /Users/physicalattraction/git/yii-app/protected/dirB/classB.php on line 3
Details
PHPUnit settings in Eclipse
bootstrap.php
<?php
include_once('AutoLoader.php');
// Register the directory to your include files
Toolbox\Testing\AutoLoader::registerDirectory(__DIR__.'/../yii-1.1.14.f0fee9');
Toolbox\Testing\AutoLoader::registerDirectory(__DIR__.'/../protected');
?>
Autoloader.php
<?php
namespace Toolbox\Testing;
/**
* This class is an auto loader for use with vanilla PHP projects' testing environment. Use it in
* the bootstrap to register classes without having to use a framework (which you can, and should if
* it's a better solution for you) and without having to use includes everywhere.
*
* It assumes that the file path in relation to the namespace follows the PSR-0 standard.
*
* IMPORTANT NOTE: When just registering directories, the class has no ability to discern
* conflicting class names in different namespaces, which means that classes with the same name will
* override each other! Always use the registerNamespace()-method if possible!
*
* Inspired by Jess Telford's AutoLoader (http://jes.st/).
*
* #see http://jes.st/2011/phpunit-bootstrap-and-autoloading-classes/
* #see http://petermoulding.com/php/psr
* #see http://www.php-fig.org/psr/psr-0/
*
* #codeCoverageIgnore
*
* #category Toolbox
* #package Testing
*
* #author Helge Söderström <helge.soderstrom#schibsted.se>
*/
class AutoLoader {
/**
* An array keeping class names as key and their path as the value for classes registered with
* AutoLoader::registerNamespace().
*
* #var array
*/
protected static $namespaceClassNames = array();
/**
* An array keeping class names as key and their path as the value for classes registered with
* AutoLoader::registerDirectory().
*
* #var array
*/
protected static $directoryClassNames = array();
/**
* Store the filename (sans extension) & full path to all ".php" files found for a namespace.
* The parameter should contain the root namespace as the key and the directory as a value.
*
* #param string $namespace
* #param string $dirName
* #return void
*/
public static function registerNamespace($namespace, $dirName) {
$directoryContents = new \DirectoryIterator($dirName);
foreach($directoryContents as $file) {
if ($file->isDir() && !$file->isLink() && !$file->isDot()) {
$newNamespace = $namespace . "_" . $file->getFileName();
$newDirName = $dirName . "/" . $file->getFilename();
static::registerNamespace($newNamespace, $newDirName);
} elseif (substr($file->getFilename(), -4) === '.php') {
$className = substr($file->getFilename(), 0, -4);
$namespacedClassName = $namespace . "_" . $className;
$fileName = realpath($dirName) . "/" . $file->getFilename();
static::$namespaceClassNames[$namespacedClassName] = $fileName;
}
}
}
/**
* Store the filename (sans extension) & full path of all ".php" files found.
*
* NOTE: This method will not be able to differentiate the same class names in different
* namespaces and will therefore overwrite class names if multiple of the same name is
* found. If possible, use registerNamespace instead!
*
* #param string $dirName
* #return void
*/
public static function registerDirectory($dirName) {
$directoryContents = new \DirectoryIterator($dirName);
foreach ($directoryContents as $file) {
if ($file->isDir() && !$file->isLink() && !$file->isDot()) {
// Recurse into directories other than a few special ones.
static::registerDirectory($file->getPathname());
} elseif (substr($file->getFilename(), -4) === '.php') {
// Save the class name / path of a .php file found.
$className = substr($file->getFilename(), 0, -4);
AutoLoader::registerClass($className, $file->getPathname());
}
}
}
/**
* Caches a found class with the class name as key and its path as value for use when loading
* on the fly. The class is registered with its class name only, no namespace.
*
* #param string $className
* #param string $fileName
* #return void
*/
public static function registerClass($className, $fileName) {
AutoLoader::$directoryClassNames[$className] = $fileName;
}
/**
* Includes a found class in the runtime environment. Strips namespaces.
*
* #param string $className
* #return void
*/
public static function loadClass($className) {
// First, see if we've registered the entire namespace.
$namespacedClassName = str_replace('\\', '_', $className);
if (isset(static::$namespaceClassNames[$namespacedClassName])) {
require_once(static::$namespaceClassNames[$namespacedClassName]);
return;
}
// Nope. Have we registered it as a directory?
$psrDirectorySeparators = array('\\', '_');
foreach($psrDirectorySeparators as $separator) {
$separatorOccurrence = strrpos($className, $separator);
if($separatorOccurrence !== false) {
$className = substr($className, $separatorOccurrence + 1);
break;
}
}
if (isset(AutoLoader::$directoryClassNames[$className])) {
require_once(AutoLoader::$directoryClassNames[$className]);
}
}
}
// Register our AutoLoad class as the system auto loader.
spl_autoload_register(array('Toolbox\Testing\AutoLoader', 'loadClass'));
?>
The Autoloader probably doesn't find the YII class. Did you try adding:
Toolbox\Testing\AutoLoader::registerDirectory(DIR.'/../yii-1.1.14.f0fee9/framework');
to your bootstrap.php file. I think that the YII class is defined in the framework directory.
Another thing which you can try is to use the composer autoloader instead.
P.S
It is a good practice to mirror your app directory/file structure in the tests directory. In your case ClassATest.php and ClassBTest.php should be separated into their own directories the same way they are separated in the protected directory.
I found that with the following changes, it worked.
Have the following directory structure
project
protected
config
main.php
test.php
controllers
models
tests
fixtures
functional
report
unit
bootstrap.php
phpunit.xml
In main.php: add the directories in which Yii looks for classes. Subdirectories are not automatically searched for by Yii, so you have to specify each directory individually here.
// autoloading model and component classes
'import' => array(
'application.models.*',
'application.models.support.*',
'application.components.*',
....
Define the following test configuration in test.php.
<?php
return CMap::mergeArray(
require(dirname(__FILE__).'/main.php'),
array(
'components'=>array(
'fixture'=>array(
'class'=>'system.test.CDbFixtureManager',
),
'db'=>array(
'class' => 'CDbConnection',
'connectionString' => 'CONNECTIONSTRING',
'emulatePrepare' => true,
'username' => 'USERNAME',
'password' => 'PASSWORD',
'charset' => 'utf8',
),
),
)
);
?>
Then, in the bootstrap file, only use the Yii Autoloader.
<?php
$yiit=__DIR__.'/../../yii-1.1.14.f0fee9/yiit.php';
$config=dirname(__FILE__).'/../config/test.php';
require_once($yiit);
// Include the following line if you want to write a WebTestCase
// require_once(dirname(__FILE__).'/WebTestCase.php');
Yii::createWebApplication($config);
?>
My test case needs a model of type Order, which is connected to a database table orders. Define a fixture in directory fixtures/Order.php.
<?php
return array(
'order1' => array(
'id' => 1011,
'order_number' => 'on_101'
)
);
?>
Make the test case as indicated on the Yii and PHPUnit websites.
class MyExportTest extends CDbTestCase
{
public $fixtures = array(
'orders' => 'Order'
);
public function test_order()
{
$order = $this->orders('order1');
$this->assertTrue($order instanceof Order);
$r = $order->order_number;
$e = "on_101";
$this->assertEquals($r, $e,
sprintf("Received order_number: \n%s\nExpected order_number: \n%s\n", $r, $e));
}
public function test_export()
{
$sut = new MyExport($tenantId, $userGroupId);
$r = $sut->method_to_test()
$e = "expected result";
$this->assertEquals($r, $e,
sprintf("Received result: \n%s\nExpected result: \n%s\n", $r, $e));
}
}

Can't create a new SplDoublyLinkedList in PHPWord tool, syntax error on 'new'

I am trying to edit the PHPWord plugin to better fit my needs. By making the list of sections that the PHPWord main class holds, I can make it so I can insert sections into any order in the document instead of just a fixed list that I can't re-order.
But I am getting an error saying syntax error, unexpected 'new' and it is driving me crazy.
Does anybody else know more about this PHPWord tool? I'm not getting answers from their Github issue tracker/forum.
Something along the lines of they have their defined classes that the tools uses and I need to add it somehow as a resource? I can't just add it in for some reason.
Mucho gracias!
EDIT:
I tried making a new object on this line OTHER than array() or SplDoublyLinkedList() and no matter what other object I try to assign that is outside of the plugin scope I get the 'new' syntax error.
I also tried new ArrayObject(); and I'm still getting the error.
PHPWord uses an Autoloader? This is their autoloader code, do I need to somehow include any extra classes I want to use in here somehow?
namespace PhpOffice\PhpWord;
/**
* Autoloader
*/
class Autoloader
{
/** #const string */
const NAMESPACE_PREFIX = 'PhpOffice\\PhpWord\\';
/**
* Register
*
* #param bool $throw
* #param bool $prepend
* #return void
*/
public static function register($throw = true, $prepend = false)
{
spl_autoload_register(array(new self, 'autoload'), $throw, $prepend);
}
/**
* Autoload
*
* #param string $class
* #return void
*/
public static function autoload($class)
{
$prefixLength = strlen(self::NAMESPACE_PREFIX);
if (0 === strncmp(self::NAMESPACE_PREFIX, $class, $prefixLength)) {
$file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $prefixLength));
$file = realpath(__DIR__ . (empty($file) ? '' : DIRECTORY_SEPARATOR) . $file . '.php');
if (file_exists($file)) {
/** #noinspection PhpIncludeInspection Dynamic includes */
require_once $file;
}
}
}
}
You have probably gotten already past this problem, but just to write out the problem answer here in case someone stumbles here and tries to make sense of this case.
As #karthikr mentioned, the problem is using object initialization with new when defining class variable (php: properties):
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
i.e. the correct way to do the initialization is to move the new to the PhpWord class constructor:
private $sections = null;
public function __construct()
{
$sections = new SplDoublyLinkedList();
...
}

php spl_autoload_register() doesn't load a class

I have an index.php that require Test1 class trough spl_autoload_register(). In the Test1 class the Test2 class is required with the same autoload but this error occurred:
Fatal error: DOMDocument::registerNodeClass(): Class Test2 does not
exist in...
I tried to see if the autoload work writing $test2 = new Test2(); and it works well. So with other tests I realized that with registerNodeClass() the autoload doesn't include the Test2 class file.
Is there anyone who can help me?
Test1.php
<?php
namespace Test;
use Test\Test2;
class Test1
{
function __construct($html)
{
$this->dom = new \DOMDocument();
#$this->dom->loadHTML($html);
$this->dom->registerNodeClass('DOMElement', 'Test2');
}
}
?>
Test2.php
<?php
namespace Test;
class Test2 extends \DOMElement
{
//bla, bla, bla...
}
?>
index.php
<?php
require_once('./autoload.php');
use Test\Test1;
$html = 'something';
$test = new Test1($html);
?>
autoload.php (it is the same used by Facebook for the php-sdk)
<?php
/**
* An example of a project-specific implementation.
*
* After registering this autoload function with SPL, the following line
* would cause the function to attempt to load the \Foo\Bar\Baz\Qux class
* from /path/to/project/src/Baz/Qux.php:
*
* new \Foo\Bar\Baz\Qux;
*
* #param string $class The fully-qualified class name.
* #return void
*/
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'Test\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/src/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});
?>
class Test2 is within namespace Test, so in order to do new Test2() you must be within the namespace Test or you can specify the fully qualified name (ie new Test\Test2()) to instantiate the class.
When you call $this->dom->registerNodeClass('DOMElement', 'Test2');, DOMDocument does something to the affect of:
$extendedClass = 'Test2';
$obj = new $extendedClass();
And it doesn't find Test2 because that code isn't called from the Test namespace.
So you would need to pass the fully qualified class name (w/ namespace).
Use: $this->dom->registerNodeClass('DOMElement', 'Test\Test2');

PHP include path and path separator confusion

I'm trying to get an opensource web application running. Its from here - https://sourceforge.net/projects/labshare-sahara/
It uses the Zend PHP framework.
My problem is with the following bit of code. It fails to find a file, and so it returns false, and the message:
"2012-08-20T00:01:08+02:00 DEBUG (7): Unable to find auth class
SAHARANS_Auth_Type_Database in include path"
is outputted to the log file.
private function _loadClass($name)
{
/* Find the class to load. */
$file = implode('/', explode('_', $name)) . '.php';
foreach (explode(PATH_SEPARATOR, get_include_path()) as $path)
{
$this->_logger->debug("does $path/$file exist?"); //I added this
if (file_exists($path . PATH_SEPARATOR . $file))
{
return new $name();
}
}
$this->_logger->debug("Unable to find auth class $name in include path.");
return false;
}
To give a bit more context I got it to print some more information to the log - so it writes to the log each time round the for loop. This is the output:
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application/../library/SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\library/SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application\models/SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\institution/SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does ./SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\php\PEAR/SAHARANS/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): Unable to find auth class SAHARANS_Auth_Type_Database in include path
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application/../library/Sahara/Auth/Type/Database.php exist?
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\library/Sahara/Auth/Type/Database.php exist
2012-08-20T00:47:07+02:00 DEBUG (7): does C:\xampp\htdocs\Sahara-WI\WI\application\models/Sahara/Auth/Type/Database.php exist?
Note: Database.php does exist in the models\Sahara\Auth\Type directory!
What immediately seemed strange is the interchange between '/' and '\' in the
paths, but trying to force a backlash (I'm using a windows machine) didn't seem to have any affect.
Thanks in advance!
PATH_SEPARATOR is ; on windows, and : on other operating system. It is used to split multiple paths, not (sub)directories and file names.
Change:
if (file_exists($path . PATH_SEPARATOR . $file));
To:
if (file_exists($path . '/' . $file));
This will work everywhere.
Well 2 things:
Use DIRECTORY_SEPARATOR and not PATH_SEPARATOR.
Use realpath() to fix any path oddities.
If anyone's interested, my autoloader looks like this (not ZF though):
<?php
namespace Application\Common;
/**
* Autoloader class
* This class will be responsible for autoloading of classes.
*/
class Autoloader {
/** #var string $namespace Namespace prefix for this instance */
private $namespace;
/** #var string $path Path prefix for this instance */
private $path;
/**
* #param string $namespace
* #param string $path
*/
public function __construct($namespace, $path) {
$this->namespace = ltrim($namespace, "\\");
$this->path = rtrim($path, "/\\");
}
/**
* Attempts to load a class.
*
* #param string $class The class name, including namespace.
*
* #return bool Success or fail based on class existence.
*/
public function load($class) {
$class = ltrim($class, "\\");
//Check to see if class is from correct namespace defined by Autoloader instance.
if (strpos($class, $this->namespace) === 0) {
//Explode by namespace parts
$namespace_parts = explode("\\", $class);
//Class would be the last element, take it out and return it
$class = array_pop($namespace_parts);
$namespace_parts[] = '';
/* Build the directory path:
The base path as defined in Autoloader
The namespace parts, each a folder
Parts of the class, separated by an underscore, become folders as well
*/
$path = $this->path . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $namespace_parts);
$path .= str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php";
$path = realpath($path);
if (file_exists($path)) {
require $path;
return true;
}
}
return false;
}
/**
* Register the function.
*/
public function register() {
spl_autoload_register(array($this, "load"));
}
/**
* Unregisters the function.
*/
public function unregister() {
spl_autoload_unregister(array($this), "load");
}
}
Use:
//Application being the common namespace prefix.
//__DIR__."Application" being the base directory.
$autoloader = new Application\Common\Autoloader("Application", __DIR__ . "Application");
$autoloader->register();
Your autoloader needs to actually require in the class, so you probably want:
if (file_exists($path . PATH_SEPARATOR . $file))
{
require $path . PATH_SEPARATOR . $file;
return new $name();
}

Categories