PHP autoload oddity - php

function __autoload($class_name) {
echo("Attempting autoload ");
if (substr($class_name, -6) == "Mapper") {
$file = 'mappers/'.$class_name.'.php';
echo "Will autoload $file ";
include_once($file);
}
}
__autoload("UserMapper");
$user = new UserMapper($adapter);
die("done");
Result:
Attempting autoload Will autoload mappers/UserMapper.php done
function __autoload($class_name) {
echo("Attempting autoload ");
if (substr($class_name, -6) == "Mapper") {
$file = 'mappers/'.$class_name.'.php';
echo "Will autoload $file ";
include_once($file);
}
}
//__autoload("UserMapper");
$user = new UserMapper($adapter);
die("done");
(I just commented out the manual call to __autoload()...)
Result:
Fatal error: Class 'UserMapper' not found in C:\Program Files\EasyPHP-5.3.5.0\www\proj\29letters\login.php on line 13
Any ideas?
And yes, I'm running PHP 5.3.5

Not sure why your example isn't working, as it should be as per the manual.
Have you tried using spl_autoload_register to register the autoloader function?

Have you set a proper include_path? You're using a relative path to include the class's file. Try an absolute path instead.
$dir = __DIR__ . '/../path/to/mappers';
$file = $dir . '/' . $class_name . '.php';
require $file;
or
// do this outside of __autoload
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../path/to/mappers';
// inside __autoload
$file = $class_name . '.php';
require $file;

Related

don't find class in root directory in use of spl_autoload_register

I use of spl_autoload_register for class auto loading like bellow
spl_autoload_register(array($this, 'mainLoader'));
function mainLoader($class) {
$dirs = explode(CLASS_SEPARATOR, $class);
$dirsLen = count($dirs);
$class_name = $dirs[$dirsLen - 1];
if ($dirsLen > 1) {
$paths = array_slice($dirs, 0, $dirsLen - 1);
$path = ROOT . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $paths) . DIRECTORY_SEPARATOR;
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
} else {
set_include_path(get_include_path() . PATH_SEPARATOR . ROOT);
}
spl_autoload_extensions(".php");
spl_autoload($class_name);
}
input class name can be class, dir_class, dir_dir_class, ...
and file can be ROOT/class.php Root/dir/class.php , Root/dir/dir/class.php, ...
but when I run program Error to me
Fatal error: Class 'class' not found in ...
why my auto loader don't work correctly??
note: this function work good in Windows but don't work in Linux Ubuntu 14.04
You're probably using camelCase names to your files.
Unix is case sensitive in file names and spl_autoload will work just with lower case.

PHP Load every class in a directory

I have coded a PHP script that includes every file in a directory. But im wondering if there is a way to load the classes in the files im including like a autoloader or something?
<?php
define("include_dir", dirname(__FILE__) . '/includes/');
foreach (scandir(include_dir) as $filename)
{
if (is_file(include_dir . '/' . $filename))
{
//its a php file, lets do this!
if (substr($filename, -4) == '.php')
{
include include_dir . $filename;
}
}
}
?>
try this-
function __autoload($class_name) {
include $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
the manual -
http://php.net/manual/en/language.oop5.autoload.php

Restrict my spl_autoloader to only load classes in my namespace?

I've just begun using autoloader lazy loading in my app, and I'm running afoul of namespacing. The autoloader is trying to load things like new DateTime() and failing. Is there a trick to making my autoloader spcific to only my own namespaced classes?
Here is the code I have currently. I suspect it is a mess, but I'm not seeing just how to correct it:
<?php namespace RSCRM;
class Autoloader {
static public function loader($className) {
$filename = dirname(__FILE__) .'/'. str_replace("\\", '/', $className) . ".php";
if (file_exists($filename)) {
include_once($filename);
if (class_exists($className)) {
return TRUE;
}
}
return FALSE;
}
}
spl_autoload_register('\RSCRM\Autoloader::loader');
Happy to RTM if someone can point to a solid example.
What I use is actually adapted from the autoloader used to Unit Test a few of the AuraPHP libraries:
<?php
spl_autoload_register(function ($class) {
// a partial filename
$part = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
// directories where we can find classes
$dirs = array(
__DIR__ . DIRECTORY_SEPARATOR . 'src',
__DIR__ . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'src',
__DIR__ . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . 'src',
);
// go through the directories to find classes
foreach ($dirs as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $part;
if (is_readable($file)) {
require $file;
return;
}
}
});
Just make sure the array of '$dirs' values point to the root of your namespaced code.
You can also take a look at the PSR-0 example implementation (http://www.php-fig.org/psr/psr-0/).
You might also want to look an into existing autoloader, like Aura.Autoload or the Symfony ClassLoader Component, although those might be overkill depending on what your requirements are.
I hope this helps.

Spl_Auto_register not loading class properly

I'm trying to learn about spl_autoload_register().
My index.php is under document root, my MyClass.php is put under document root /MyProject/MyClass/MyClass.php
Here's my index.php
<?php
define('CLASSDIR', 'mylib');
define('BASEPATH', #realpath( dirname (__FILE__).'/../').'/'.CLASSDIR);
spl_autoload_register(null, false);
spl_autoload_extensions('.php');
// PSR-0 provided autoloader.
function autoLoader($className){
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strrpos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= BASEPATH.'/'.str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
require $fileName;
}
spl_autoload_register('autoLoader');
$obj = new MyClass();
$obj->test();
?>
Here's my Class: MyClass.php
<?php
namespace MyProject\MyClass;
class MyClass{
public function __contruct(){
echo('weird');
}
function test(){
echo 'issue';
}
}?>
Here's the error:
Fatal error: Call to undefined method MyClass::test() in /path/to/file/index.php on line 26
So, I'm assuming it found the class (since it didn't complain)? But the messages 'weird' and 'issue' are not displayed. Telling me that the constructor didn't fire.
Okay, assuming your class file is located in a seperate folder called classes (example)
Structure like this:
DOCUMENT_ROOT/
->index.php
->classes/
->Myclass/
->Myclass.php
Somewhere on your index.php You'd have something looking like this:
<?php
DEFINE('__BASE', realpath(dirname(__FILE__)));
require_once('load.php');
?>
Now your load.php file should have the __autoload() function in there, looking something like this:
// Auto load function to load all the classes as required
function __autoload($class_name) {
$filename = ucfirst($class_name) . '.php';
$file = __BASE . DIRECTORY_SEPARATOR .'classes/' . ucfirst($class_name) . $filename;
// First file (model) doesnt exist
if (!file_exists($file)) {
return false;
} else {
// include class
require $file;
}
}
EDIT:
If you'd like to do it with spl_autoload_register(), you'd have something similar to this in your load.php
// Auto load function to load all the classes as required
function load_classes($class_name) {
$filename = ucfirst($class_name) . '.php';
$file = __BASE . DIRECTORY_SEPARATOR .'classes/' . ucfirst($class_name) . $filename;
// First file (model) doesnt exist
if (!file_exists($file)) {
return false;
} else {
// include class
require $file;
}
}
spl_autoload_register('load_classes');

How to use __autoload for different folders?

I am trying to autoload classes that are in different folders. Is that possible?
function __autoload($class){
require $class.'.php';
require 'libs/'.$class.'.php';
//this won't work.
}
I want to autoload classes that are either in libs folder or on the root. Any thoughts? Thanks a lot.
First, I suggest you look into spl_autoload_register, which is superior for doing this.
Second, you should use is_file to test whether the file exists, then try to load it. If you require a file that doesn't exist, your script will halt.
spl_autoload_register(function($class) {
if (is_file($class . '.php')) {
require $class . '.php';
} elseif (is_file('libs/' . $class . '.php')) {
require 'libs/' . $class . '.php';
}
});
If you have multiple folders where the file could be, you could do something like this:
spl_autoload_register(function($class) {
$folders = array ('.', 'libs', 'somewhere');
foreach ($folders as $folder) {
if (is_file($folder . '/' . $class . '.php')) {
require $folder . '/' . $class . '.php';
}
if (class_exists($class)) break;
}
});

Categories