Domanda

So I already asked this question here earlier, but the solutions provided didn't work for me. Here's my setup:

/mylib
    /Vendor/Module/MyClass.php
/document_root
    index.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');

function autoLoader($className){

    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        echo 'does it come here? nope.'; 
        $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 = new \Vendor\Module\MyClass();

$obj::test();

 ?>

Here's my MyClass.php

<?php

namespace Vendor\Module;

class MyClass{

    public function __construct(){
        echo 'weird';
    }

    public function test(){
        echo 'strange';
    }
}
?>

None of my echo's display anything. Obviously my class is also not loaded. Instead I get this error.

Fatal error: Call to undefined method MyClass::test() in /<documentroot>/index.php on line 29

Please help. I've been stuck on this for quite a while now and the rest of my development is suffering. I tried moving to spl_autoload_register() only because it's the recommended way. Now the lost time is making me regret it.

È stato utile?

Soluzione 2

F**k yes. Yes, I can take the liberty to swear on a public forum this one time.

A huge shout out to @Shivan Raptor for helping me along the way and not giving up.

There were numerous minor issues in the auto-loader function. But the debugging took me so long for just a simple reason that I couldn't see any echo messages. Only lord and XAMPP knows why. Seemed like XAMPP had somehow cached the class on first run or something and no changes later showed any effect. But creating a new class and class file all of a sudden started showing all my echo including the ones inside autoload. Anyone who has picked up the auto-loader code from the link below, please ensure you look at all the variables' values. It doesn't work "out of the box", if you don't keep everything in the document root. And if you are new to both PSR-0 and concept of auto loading, this can kill at least a sizable portion of your perfectly capable brain cells.

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

Here's the final index.php that worked for me.

<?php

define('CLASSDIR', 'mylib');
define('BASEPATH',  @realpath( dirname (__FILE__).'/../').'/'.CLASSDIR);

spl_autoload_register(null, false);
spl_autoload_extensions('.php');

function autoLoader($className){
    $className = ltrim($className, '\\');
    $classPath  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {    
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $classPath = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR;
    }
    $fileName = BASEPATH.'/'.$classPath.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
    require $fileName;
}

spl_autoload_register('autoLoader');

$obj = new \Vendor\Module\MyClass();
$obj::test();
?>

Altri suggerimenti

Your are calling the test() function incorrectly (using static way?).

Call the function with:

$obj = new MyClass();
$obj->test();

If you intend to use static method like MyClass::test(), declare your function in your class as:

public static function test() {
}

Moreover, your autoloader is over-complicated. It can be simplified as:

$class_dir = array(
    '/mylib/Vendor/Module/',
    // Add more paths here ( or you can build your own $class_dir )
);

function class_loader($class_name) {
    global $class_dir;
    foreach ($class_dir as $directory) {
        if (file_exists($directory . $class_name . '.php')) {
            require_once($directory . $class_name . '.php');
            return;
        }
    }
}
spl_autoload_register('class_loader');

3rd edit:

I noticed the path you set is incorrect.

$fileName .= BASEPATH.'/'.str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

It should be:

$filename = BASEPATH .'/' . $filename . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

As said before, it can be easily debugged by echoing the value of $filename.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top