I'm looking for a way to load classes into PHP without using hardwired names.
The idea is the script will load a text file with names of 'components'(classes), then load them by the names in the file. For example:
<xml><Classes><class name="myClass"/></Classes></xml>
When the PHP is run, it would need to do something like this:
require_once {myClass}".class.php";
var myclass = new {myClass}();
require_once $class . ".class.php";
$myclass = new $class;
See http://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new.
Your example is almost correct as is. You can just replace {myClass} with $myClass and it should work.
Here's a simple example of how this could be used:
File: myClass.class.php
<?php
class myClass {
public $myVar = 'myText';
}
?>
File: test.php
<?php
$className = "myClass";
require_once $className . ".class.php";
$myInstance = new $className;
echo $myInstance->myVar;
?>
This should output "myText" to the screen, the contents of your dynamically included class property.
Use the ReflectionClass for this.
require_once $class . ".class.php";
$refl = new \ReflectionClass($class);
$params_for_construct = array($param1, param2);
$instance = $refl->newInstanceArgs($params_for_construct);
Why not just use autoloader
spl_autoload_register(function ($class) {
require 'class_folder/' . $class . '.class.php';
});
Related
I just started learning PHP from a book. In the OOP chapter there is an explanation of the __autoload() function for "Automatically Load Class Files" but my book doesn't say where I should declare this function.
I tried to Google it and in the PHP documentation but I really can't find where I should declare this function. In "global scope" (I don't know if it is the same as JavaScript)? Inside the class that should be autoloaded? Or in the "local scope" of the class where I have to load the class?
The way of using the __autoload() function is :
<?php
function __autoload($class){
if(file_exists($class . ".php")){
require_once $class . ".php";
}
}
$class1 = new Class1();
$class2 = new Class2();
On the very top of your page declare the function than you can start using it just like in the example below .
If you want it to be available site-wide than consider making a new file type the code there and include that file in the top of your page.
something.php
<?php
function __autoload($class){
if(file_exists($class . ".php")){
require_once $class . ".php";
}
}
Than just include something.php on all the pages you need like :
<?php
require_once 'something.php';
$class1 = new Class1();
$class2 = new Class2();
so i've started using namespaces and read some docs but I seem to be doing something wrong.
First off is my application structure which is build like this:
root
-dashboard(this is where i want to use the autoloader)
-index.php
--config(includes the autoloader)
--WePack(package)
---src(includes all my classes)
now in the src directory I included the classes with:
namespace WePack\src;
class Someclass(){
}
the content of config.php is:
<?php
// Start de sessie
ob_start();
session_start();
// Locate application path
define('ROOT', dirname(dirname(__FILE__)));
set_include_path(ROOT);
spl_autoload_extensions(".php"); // comma-separated list
spl_autoload_register();
echo get_include_path();
and I use it like this in my index.php
require_once ('config/config.php');
use WePack\src;
$someclass = new Someclass;
this is what the echo get_include_path(); returns:
/home/wepack/public_html/dashboard
which is what I want I guess. but the classes are not loaded and nothing is happening. I'm obviously missing something but I can't seem to figure it out. could you guys take a look at it and explain to me why this isn't working?
The problem here is, that you don't register a callback function with spl_autoload_register(). have a look at the official docs.
To be more flexible, you can write your own class to register and autoload classes like this:
class Autoloader
{
private $baseDir = null;
private function __construct($baseDir = null)
{
if ($baseDir === null) {
$this->baseDir = dirname(__FILE__);
} else {
$this->baseDir = rtrim($baseDir, '');
}
}
public static function register($baseDir = null)
{
//create an instance of the autoloader
$loader = new self($baseDir);
//register your own autoloader, which is contained in this class
spl_autoload_register(array($loader, 'autoload'));
return $loader;
}
private function autoload($class)
{
if ($class[0] === '\\') {
$class = substr($class, 1);
}
//if you want you can check if the autoloader is responsible for a specific namespace
if (strpos($class, 'yourNameSpace') !== 0) {
return;
}
//replace backslashes from the namespace with a normal directory separator
$file = sprintf('%s/%s.php', $this->baseDir, str_replace('\\', DIRECTORY_SEPARATOR, $class));
//include your file
if (is_file($file)) {
require_once($file);
}
}
}
after this you'll register your autoloader like this:
Autoloader::register("/your/path/to/your/libraries");
Isn't this what you mean:
spl_autoload_register(function( $class ) {
include_once ROOT.'/classes/'.$class.'.php';
});
That way you can just call a class like:
$user = new User(); // And loads it from "ROOT"/classes/User.php
I have a PHP project structured as:
--root
|--dr1
| |---dr2
| |--testclass.php
|--start.php
|--bootstrap.php
The testclass.php contains:
namespace dr1\dr2;
class testclass {
...
}
The bootstrap.php contains:
define('DIR_SEP', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__) . DIR_SEP);
function __autoload($class)
{
$path = ROOT . str_replace('\\', DIR_SEP, $class);
$file = $path . '.php';
if( is_file($file) ) require_once($file);
}
spl_autoload_extensions('.php');
spl_autoload_register('__autoload');
and The start.php contains:
$class = 'dr1\dr2\testclass.php';
$obj = new $class();
When I run the start.php, I got the message dr1\dr2\testclass.php is not found on start.php on line 5. I could not figure out why. would anybody help. thanks a lot.
The autoloader looks correct, so the problem is the Classname testclass.php. In you source-file it's just testclass without the .php - so if you adjust your $class-variable like that it should work:
$class = 'dr1\dr2\testclass';
$obj = new $class();
To access your class you could do
$class = new testclass();
I am just learning how to use spl_autoload_register
I have a folder structure that looks like this:
lib/projectname/home/homepage.php
so if I include the file like this it works:
include("lib/projectname/home/homepage.php");
$home = new homepage();
I have added in an autoload.php file which looks like this:
function myclass($class_name) {
$class_name = str_replace('_', DIRECTORY_SEPARATOR, $class_name) . '.php';
require_once($class_name);
}
spl_autoload_register('myclass');
Now if I try to use the class I am referencing it like this:
require_once("autoload.php");
$home = new lib_projectname_home_homepage;
when i do this, i get the following error:
Fatal error: Class 'lib_projectname_home_homepage' not found
So it appears as if the loading of the class file is working, but its not finding the class inside the file?
The actual homepage.php file looks like this:
class homepage {
function __construct(){
echo "homepage";
}
}
What do I need to change in order to make this work properly?
change
class homepage {
function __construct(){
echo "homepage";
}
}
to
class lib_projectname_home_homepage {
function __construct(){
echo "homepage";
}
}
or change:
require_once($class_name);
to
require_once('lib/projectname/home/' . $class_name);
and then:
$home = new homepage();
concept of autoloader is simply to find class with a given name. it does not change class name on the fly.
i'm updating my code and trying to use spl_autoload_register but IT SIMPLY DOESN'T WORK!!!
I'm using PHP 5.3.8 - Apache 2.22 on Centos / Ubuntu / Win7 and trying to echo something but i get nothing instead... have been trying to make it work for the last 3 hours with no result... this is driving me mad!!!
class ApplicationInit {
// Constructor
public function __construct() {
spl_autoload_register(array($this, 'classesAutoloader'));
echo 'construct working...!';
}
// Autoloading methods
public function classesAutoloader($class) {
include 'library/' . $class . '.php';
echo 'autoload working...!';
}
}
first echo from __construct works but the "classesAutoloader" doesn't work at all, this class is defined in a php file within a folder and i'm calling it from index.php like follows:
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', getcwd() . DS);
define('APP', ROOT . 'application' . DS);
// Initializing application
require(APP.'appInit.php');
$classAuto = new ApplicationInit();
any help is truly appreciated, thanks in advance!
It seems like you're doing the wrong thing. The function that you pass to spl_autoload_register is what's responsible for loading the class file.
Your code is calling
$classAuto = new ApplicationInit();
but by that time, ApplicationInit is already loaded so the autoload function doesn't get called
A more logical way would be for you to to call
spl_autoload_register(function($class){
include 'library/' . $class . '.php';
});
Then when you call
$something = new MyClass();
And the MyClass is not defined, then it will call your function to load that file and define the class.
What is your problem? Your code is working correctly.
class ApplicationInit {
public function __construct() {
spl_autoload_register(array($this, 'classesAutoloader'));
echo 'construct working...!';
}
public function classesAutoloader($class) {
include 'library/' . $class . '.php';
echo 'autoload working...!';
}
}
$classAuto = new ApplicationInit(); //class already loaded so dont run autoload
$newclass = new testClass(); //class not loaded so run autoload