Because SPL sucks, right?



  • Disclaimer: PHP

    I've been lurking for a while, chuckling at a lot of the code. A couple of times, I also thought about submitting a couple of things seen around. This one, however, just needed to be submitted. It's so big, so mind-boggingly WTF, that it just deserved it. It is in production and has been for six months.

        public static function classExists($className)
    {
        $className = ucfirst($className);
    
        if (! empty(self::$loadableClasses) && isset(self::$loadableClasses[$className]))
            return true;
    
        $paths = explode(PATH_SEPARATOR, get_include_path());
    
        while ($path = array_shift($paths)) {
            
            $filename = realpath($path . '/lib/' . str_replace("\\", DIRECTORY_SEPARATOR, $className) . '.php');
            if (file_exists($filename)) {
                self::$loadableClasses[$className] = $filename;
                return true;
            }
        }
    
        return false;
    }
    

    What you are seeing there is a replacement for class_exists in PHP - explained at: http://php.net/class_exists

    For those who have not done any PHP recently, a long while back, SPL autoload functions were added along with a way to easily register them (spl_autoload_register). This meant that the include_path was no longer the de facto place for class files (phew!). class_exists bears this in mind by calling each autoload method, in succession, to check if the class actually does exist.
    This snippet decided that SPL was essentially bullshit and that the include path was the law. It also decides to statically keep a cache of loaded classes (if a class is loaded, class_exists($className, false) does the same in one syscall).

    When asked about it, the guy who coded it (lead dev) said that it is because class_exists throws warnings. When told that it doesn't, and has never, thrown warning on its own, he backed it up with this snippet:

    spl_autoload_register(function($className) {
        include 'lib/'.ucfirst(str_replace("\\", DIRECTORY_SEPARATOR, $className)).'.php';
    });
    

    Who knew that includes threw warnings?



  • Sound Pressure Level?



  • Standard PHP Library



  • I kept thinking of SWPL.



  • The PHP manual comments is generally a cesspool of bad codes by confident idiots.



  • If I read a method name like that it has a 99% probability of being a WTF, in whichever language you choose.


  • Discourse touched me in a no-no place

    @Eldelshell said:

    If I read a method name like that it has a 99% probability of being a WTF, in whichever language you choose.

    It's a reasonable thing as part of a general introspection package. But it isn't usually something that you'd ever want to replace; it's not usually easy to write correctly.You've not lived coded until you've written your own object system…


  • SockDev

    This is why FILE_NOT_FOUND is a thing. And yes, include throws a warning if the file can't be found (which is why it is different to require which throws a fatal error that can't be caught as an exception last time I checked)

    I'm currently rocking a simplistic autoloader in my current build project - it's an add-on for SMF and needs to be kept away from other stuff because other add-on writers are generally not so fussy about cluttering namespaces and stuff hence I actually check the name of the class before doing anything with it (and yes, $sourcedir is an artefact of SMF not my stuff)

    This converts ArantorProduct_Model_Thing to $sourcedir/product_src/Model/Thing.php, in case it wasn't clear.

    	public static function autoloader($class)
    	{
    		global $sourcedir;
    
    		if (strpos($class, 'ArantorProduct') === 0)
    		{
    			$fileparts = explode('_', $class);
    			array_shift($fileparts);
    			$file_path = $sourcedir . '/product_src/' . implode('/', $fileparts) . '.php';
    			if (!file_exists($file_path))
    			{
    				throw new RuntimeException($file_path . ' not found');
    			}
    			require_once($file_path);
    		}
    	}
    

    The reason for the exception throwing is because I also do a routing thing which figures out the name of the class from the URL and attempts to load it by way of a try-catch (which means this and subsequently any other uncaught exception from that controller gets caught)

    For anyone thinking this is a WTF, you're half right, it sort of is. But it's based on SMF's age where it doesn't use exceptions for anything and is still mostly procedural anyway - but I'm using classes and exceptions for things (where feasible, it's not always feasible)



  • In SMF's age, before spl autoloaders and the ubiquity of the __autoload magic (global) function, that isn't a WTF. Well, not much of one.

    Add in spl autoloaders and the static class lookup map in the example I've thrown, though, and you have a stellar-class WTF.


  • SockDev

    Yup, it's not much of one for its time (it doesn't even use __autoload itself though I made sure to test for and add to stack when I declared my own with spl_autoload_register to actually add __autoload to the stack since SPL won't call __autoload itself as per manual)

    But in the case you've got, that's a fantastic WTF.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.