PHP autoload looking in current php file - php

In file: deckclass.php , with DOCROOT set to /var/www/Proj/application/controllers
getting error: Fatal error: Class 'Cardclass' not found in /var/www/Proj/application/controllers/deckclass.php on line 38
Why is it searching current php file and not DOCROOT folder?
function __autoload($class_name)
{
//class directories
$filename = DOCROOT .strtolower($class_name) . ".php";
if ( file_exists($filename) )
{
require_once ($filename);
}
else {
throw new Exception("Unable to load $class_name.");
}
}
$card = new Cardclass();

You can use define('ROOT', dirname(__FILE__)); and define('DS', DIRECTORY_SEPARATOR);
Tip
spl_autoload_register() provides a more flexible alternative for
autoloading classes. For this reason, using __autoload() is
discouraged and may be deprecated or removed in the future.
So do code should look like this:
<?php
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__)); //This is full path
spl_autoload_register('Autoloader'); //You can use annonymous function here
function Autoloader($class_name){
$filename = ROOT.DS.strtolower($class_name).".php";
var_dump($filename);
if(file_exists($filename)){
require_once ($filename);
}else{
throw new Exception("Unable to load ".$class_name."in".$filename);
}
}
$card = new Cardclass();
With __autoload:
<?php
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__)); //This is full path
function __autoload($class_name){
$filename = ROOT.DS.strtolower($class_name).".php";
var_dump($filename);
if(strpos($class, 'CI_') !== 0) {
if(file_exists($filename)){
require_once ($filename);
}else{
throw new Exception("Unable to load ".$class_name."in".$filename);
}
}
}
$card = new Cardclass();

Related

Autoloading with namespaces

My structure:
/test/init.php
/test/sub/Info.php
init.php:
<?php
namespace test;
$namespaces = function($path) {
//echo $path; = test\sub\Info
if (preg_match('/\\\\/', $path)) {
$path = str_replace('\\', DIRECTORY_SEPARATOR, $path);
}
//echo $path; = test\sub\Info
if (file_exists("{$path}.php")) {
require_once("{$path}.php");
}
};
spl_autoload_register($namespaces);
$info = new sub\Info();
And Info.php:
<?php
namespace test\sub;
class Info
{
public function __construct()
{
echo 123;
}
}
Why this isn't working?
I use Windows, so why DIRECTORY_SEPARATOR == \?
EDIT:
Sorry, I updated my question. I forgot to paste spl_autoload_register on stackoverflow.
Your autoloader ideally needs to be defined outside of a namespace, at the top level of the directory structure - the way you've got it set up at the moment, it's trying to include the file test/sub/Info.php from within the test directory, rather than from the root (i.e. test/test/sub/Info.php, which doesn't exist)
If you remove the namespace prefix test from both files (so remove it entirely from init.php and just have namespace sub; in sub/Info.php) then it will work correctly. The other option would be to move the autoloader into a file in the root directory, so that the namespaces again match up with the file-system layout.
You are using a relative path, so there are several things that could be wrong... You can see which is the current working directory by doing:
echo getcwd();
You could also try something like this:
$namespaces = function($class) {
$basepath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR;
$file = $basepath . str_replace('\\', DIRECTORY_SEPARATOR, $class) . ".php";
if (!file_exists($file) || !is_readable($file)) {
return false;
}
require_once($file);
return class_exists($class, false);
};
Variable $basepath could be also a defined constant, or a variable from a config file...

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

spl_autoload_reqister classes not getting loaded

I have a folder structure that looks like
base_dir-
Includes.php
Libs-
Database.php
Log.php
Cofing.php
Models-
someClass.php
Scheduled-
test.php
My Includes.php has
spl_autoload_register(NULL, FALSE);
spl_autoload_extensions('.php, .class.php, lib.php');
function libLoader($name) {
$file = 'Libs/' . $name . '.php';
if (!file_exists($file)) {
// throw new Exception("Error Loading Library: $file does not exists!", 1);
return FALSE;
}
require_once $file;
}
function modelLoader($name) {
$file = 'Models/' . $name . '.php';
if (!file_exists($file)) {
// throw new Exception("Error Loading Library: $file does not exists!", 1);
return FALSE;
}
require_once $file;
}
spl_autoload_register('libLoader');
spl_autoload_register('modelLoader');
My someClass.php has
require_once '../Includes.php';
class someClass extends Database
{
public function __construct() { return 'hello world'; }
}
And test.php has
require_once '../Includes.php';
try {
$loads = new someClass();
} catch (Exception $e) {
echo "Exception: " . $e->getMessage();
}
When I run test.php I get someClass not found on .../Scheduled/test.php
Does spl works with extended classes like someClass.php or do I need to include the class to be exended?
And why it wouldnt find someClass.php?
Thanks
Change
$file = 'Models/' . $name . '.php';
to
$file = __DIR__ . '/Models/' . $name . '.php';
in your models autoloader (and the equivalent in your libLoader) to ensure that it's searching from the correct directory, and not the directory where your test.php file is located

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');

PHP autoload oddity

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;

Categories