Jump to content

Crazy autoload behaviour!


NotionCommotion

Recommended Posts

Please help.  I have tried to condense the following code to make it easier for someone to shed insight.  The results make totally no sense to me.

 

I have the following two lines of code:
 

require_once('/var/www/bidjunction/application/classes_3rd/htmlpurifier/library/HTMLPurifier.auto.php');
$config = HTMLPurifier_Conf::createDefault();

Let me explain what happens in these two lines of code.  First....

require_once('/var/www/bidjunction/application/classes_3rd/htmlpurifier/library/HTMLPurifier.auto.php'):

HTMLPurifier.auto.php is shown below:

<?php

/**
 * This is a stub include that automatically configures the include path.
 */

set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
require_once 'HTMLPurifier/Bootstrap.php';
require_once 'HTMLPurifier.autoload.php';

// vim: et sw=4 sts=4

The only thing Bootstrap.php does is define a class and execute the following line:
 

define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));

The only thing HTMLPurifier.autoload.php does is execute HTMLPurifier_Bootstrap::registerAutoload()  (which was one of the classes defined in Bootstrap.php). The only thing HTMLPurifier_Bootstrap::registerAutoload() does is:

spl_autoload_register(array('HTMLPurifier_Bootstrap','autoload'), true, true);

Now the second line:

$config = HTMLPurifier_Conf::createDefault();

I expected that HTMLPurifier_Conf::createDefault() would be executed, but no, instead the script goes to HTMLPurifier_Bootstrap:autoload() which returns false.

Next, the script goes to function PHPMailerAutoload() which is in PHPMailerAutoload.php.

What!!!  What does PHPMailerAutoload have to do with this?

 

While a perfect answer would be great, general comments and a strategy to troubleshoot be the next best thing.

 

I am stumped! Please help.

Link to comment
Share on other sites

I expected that HTMLPurifier_Conf::createDefault() would be executed, but no, instead the script goes to HTMLPurifier_Bootstrap:autoload() which returns false.

Because if the class is not defined, it starts calling autoload functions until one of them defines the class.

 

Next, the script goes to function PHPMailerAutoload() which is in PHPMailerAutoload.php.

 

What!!!  What does PHPMailerAutoload have to do with this?

PHPMailer has it's own autoloader registered to load it's classes. There can be a chain of different autoloaders. PHP will call each one in the chain until one of them defines the required class. If none of them define it, you get an error.

Link to comment
Share on other sites

Okay, I have a clue.

 

I used the same two lines of code both in my application, and just all by themselves:

require_once('/var/www/bidjunction/application/classes_3rd/htmlpurifier/library/HTMLPurifier.auto.php');
$config = HTMLPurifier_Conf::createDefault();

They work when by them self.  The only difference than I could see is in HTMLPurifier_Bootstrap::registerAutoload().

public static function registerAutoload()
{
    $autoload = array('HTMLPurifier_Bootstrap', 'autoload');
    if (($funcs = spl_autoload_functions()) === false) {
        spl_autoload_register($autoload);
    } elseif (function_exists('spl_autoload_unregister')) {
        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
            // prepend flag exists, no need for shenanigans
            spl_autoload_register($autoload, true, true);
        } else {
            //something else
        }
    }
}

When running by themselves, the first IF statement is true, and spl_autoload_register($autoload); is executed.

 

When running in my application, the first IF statement is false, and the next ELSEIF and following IF statement is true, and spl_autoload_register($autoload, true, true); is executed.

 

What does this mean, and why the dramatic difference in behavior?  I am okay with no specific answer, but just another mission to investigate.

 

Thank you

Link to comment
Share on other sites

Unfortunately for me, the following script runs without errors.  Like in my application, it uses the autoload_register with the true,true arguments, but finds the static class.

 

What would make one scenario find the correct class, yet not the others?  I am not expecting a definitive answer (but give one if you have one!), but a process to troubleshoot.

 

Thank you

<?php
require_once ('../../application/classes_3rd/PHPMailer/PHPMailerAutoload.php');
class myPHPMailer extends PHPMailer {
    public function __construct($allow_exceptions=false){
        $this->isSMTP();
        $this->SMTPDebug = 0;
        $this->Debugoutput = 'html';
        $this->Host = "smtp.gmail.com";
        $this->Port = 587;
        $this->SMTPSecure=true;
        $this->SMTPAuth = "tls";
        $this->Username = "fu";
        $this->Password = "bar";
    }
}

$mail = new myPHPMailer();
$mail->AddReplyTo('x@x.com','x');
$mail->SetFrom('y@y.com','y');
$mail->Subject  = 'Hi';

require_once '../../application/classes_3rd/htmlpurifier/library/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$dirty_html='<bla>Bad</bla><p>Good</p>';
$clean_html = $purifier->purify($dirty_html);  
echo($clean_html);
?>
Link to comment
Share on other sites

What is the code for your auto loader function? Have you checked that it is able to find the class files when requested and include them?

 

Hey Kicken,

 

Don't know and don't think so.

 

Auto loader functions are on my list to get better on.

 

As the autoload object/array seems to get modified in multiple places, is it possible to display the current settings at any given moment in time?

 

PS.  Thank you very much.  This has got me stumped.

Link to comment
Share on other sites

Did you define the autoload function? If so, what is it defined as?

 

$autoload = array('HTMLPurifier_Bootstrap', 'autoload');
spl_autoload_register($autoload, true, true);
That tells PHP to call the HTMLPurifier_Bootstrap::autoload() function whenever it needs to load any undefined class. You need to have that function defined as a member of the class and it needs to try and locate the desired class.

class HTMLPurifier_Bootstrap {
   public static function autoload($class){
      //Find definition of $class
      //Load definition using require
   }
}
Your HTMLPurifier_Bootstrap::registerAutoload seems needlessly complex too. All you should need to do is call spl_autoload_register. I'm not sure why you have it doing all the other stuff. Seems like it's probably in some attempt to ensure your function is first in the chain, which is unnecessary.
Link to comment
Share on other sites

Ugg,

 

I used:

$config = HTMLPurifier_Conf::createDefault();

And should have been using:

$config = HTMLPurifier_Config::createDefault();

With the static functions and autoclasses, it was not very obvious.  Other than attention to detail, are there any other takeaways?  Are there better ways to troubleshoot this scenario?

 

In regards to "HTMLPurifier_Bootstrap::registerAutoload seems needlessly complex", it is not mine, but the script which comes with http://htmlpurifier.org/.

 

Thank you for your help!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.