Topic: xajax and __destruct

Hi folks,

I have a strange problem. After some funny tests with xajax 0.5_standard I want it to integrate in my OO project. (php 5.2.2)

I have a class like this:

class c_html_site {

  function __construct() {
      ... doing here xajax things , everything ok

      .... begin html output bla bla
  }

  function someHtml() {
     ... some html output
  }


  function __destruct() {
     echo "</body></html>";
  }
}

$a = new c_html_site();
$a -> someHtml();

Without xajax my project works like designed, the constructor begins the html site, then all other output and when php is closed, the destructor will be called and you have a normal html site.

Integrating xajax, the process hangs when I press an xajaxe'd button.
After analyzing the problem I found out, that the reason for the hang is the echo statement of the destructor.
After removing the echo, resp. move the statements into the someHtml method, everything is fine, the process is back and is changing some <divs> or what you expected.

So don't missunderstand: I have no problem with registering methods or wrong javascript output.

The problem occurs in any destruct method of my classes with print or echo statements.
Strange: Even so when the class with an destructor thats doing some output has nothing to do with xajax (no $xajax->method, no registered methods with xajax), the site hangs after starting the xajax javascript by pressing an prepared button.

I was trying to google the problem , but with no success.

To reproduce the problem, simple add an echo "test" or an print "test" to one of your destructors.

As soon as I remove output from the destructor, all is fine.
I any case the source of the site looks in both cases identically.

Maybe I'm wrong, but I thought theres no problem to make outpout in destructors.

Any help?

Re: xajax and __destruct

Hi,


Generally speaking you cannot echo anything to the browser while an xajax call is in progress. It is expecting an xajax response from the server and gets all messed up if anything unexpected shows up.

Try turning on the xajax debugger ($xajax->configure('debug',true);) and see just what the complaint is.

How do the constructor and someHTML() functions output their content? The same should suffice in the destructor I would think.

Ed

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: xajax and __destruct

Hello Ed,


I think the reason for the error is the /html/body tags, but I don't understand the problem.

Do you mean, that my integration of ajax mentioned above is wrong? So the entire page will be rebuild , not only the <div> part?
Or what do you mean with "... cannot echo anything to the browser while an xajax call is in progress ..."?

I don't understand why the output of any destructor within the script is part of the ajax requests.


Okay, the debug output comes here:

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

ERROR: ResponseReceived: Invalid response XML: The response contains an unexpected tag or text: {data}.

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

RECEIVED [status: 200, size: 130 bytes, time: 102ms]:
<?xml version="1.0" encoding="utf-8" ?>
<xjx>
<cmd cmd="as" id="submittedDiv" prop="innerHTML">S15:12:50</cmd>
</xjx></head><body>

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

SENT [36 bytes]

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

SENDING REQUEST

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

CALLING:
xjxfun: testMethod
URI:
http://localhost:83/~cbilz/framework/rot3.phtml

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

POST: xjxfun=testMethod
&xjxr=1267020770731

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

INITIALIZING REQUEST OBJECT

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

PREPARING REQUEST

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

PROCESSING PARAMETERS [0]

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

INITIALIZING REQUEST

Wed Feb 24 2010 15:12:50 GMT+0100 (CET)

STARTING XAJAX REQUEST

Re: xajax and __destruct

Here's my guess...

I think the problem may be the placement of your code instantiating the class and calling its method. On an XJAX PHP page everything BEFORE the processRequest() call is executed every time the page loads. If this is happening, your code would run when an xajax call comes in and the echo to the browser hoses things up as the xajax js is waiting for some XML from the server and you get the "invalid response XML" thing.

Code: PHP

RECEIVED [status: 200, size: 130 bytes, time: 102ms]:

<?xml version="1.0" encoding="utf-8" ?>

<xjx>

<cmd cmd="as" id="submittedDiv" prop="innerHTML">S15:12:50</cmd>

</xjx></head><body> <<--Your html output from the destructor...

 

Does this fit with your  PHP layout?

Edit:

I think I am off base in my guess.

Do you register the class as a callable object and call its methods from the browser using xajax calls? If so, the class is instantiated and destroyed at each call thus the destructor's output that messes up the expected response from the server.

Can you post the class code?

Ed

Last edited by edrobinson (2010-02-24 4:48:20 PM)

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: xajax and __destruct

Okay, here's my code:


Code: PHP

require_once( "xajax/xajax_core/xajax.inc.php" );



class C_RUN {



    public $AJAX;



    function __construct() {



    $this->AJAX = new xajax();

   

    $this->AJAX->configure('javascript URI', 'xajax/');

    $this->AJAX->configure('debug',true);

    $this->runinit();

    }



    function runinit() {



    $this->AJAX->processRequest();

    }

}



class C_HTML_SITE extends C_RUN {



    function run() {



//    echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';



    echo '<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">';



    echo '<head>';

   

    $this->AJAX->printJavascript();



    echo '</head>';



    echo '<body>';



    }



    function __destruct() {



    echo '</body>';

    echo '</html >';

    }

}



class CAJAX extends C_HTML_SITE {





    function testMethod()

    {

        $objResponse=new xajaxResponse();

        $objResponse->assign( "submittedDiv", "innerHTML", date("H:i:s"));

        return $objResponse;

    }

   

    function runinit() {



    $this->AJAX->registerFunction(array(&$this,"testMethod"));

   

    parent::runinit();

    }





    function run() {



    parent::run();



    echo '<div id = "submittedDiv"></div><p>';



    echo '<button onclick="xajax_testMethod()" >CLICK ME</button>';

    }

   

}



$a = new CAJAX;



$a->run();

 

If the script is called the first time, the workflow will be the following:

1. CRUN::constructor will be called
- instantiate xajax,configure
3. CAJAX::runinit() called
- register the method  xajax
4. CRUN::runinit() called
- process Request for xajax

In my opinion, until step 4. there will be no output produced

5. CAJAX::run() called
6. C_HTML_SITE::run() called
- begin html output
- begin head
- print javascript of xajax
- end head
- begin body
7. CAJAX::run() called
- make a div for xajax
- make a button
8. the script finished, C_HTML_SITE::destructor will be called
- end body
- end html

So, if the script will be called the first time, CAJAX will be created an at the end destroyed, so the destructor producing the output.
But what happens if I press the button?
You say, the well known concern that xajax is doing the job with the part of the script before ->processRequest(), in my case until step 4.
I suspect that xajax is creating the object CAJAX again, but supressing its output, but not of the destructors.
I rationalize this idea because when I move the two echo's f the destructor down to the CAJAX::run() method, the site works without errors.
But it's mysterious why it is so.
Because C_HTML_SITE and CRUN works as abstract classes, it's not pretty to delegate abstract work - here the finish of the site - to the project classes (CAJAX).

Last edited by frameworker (2010-02-27 12:42:23 AM)

Re: xajax and __destruct

Sorry to be so long in replying...

As long as the destructor in C_HTML_SITE is left in place it will be invoked when the instance of CAJAX goes away and it will mess up the XML expected by the XAJAX Javascript in the browser.  Using the Firebug console showing xml errors shows a "not well formed" XML error so I would expectt XAJAX to complain about it as well.

It seems to me that the entire html page should be created in the run() function of the C_HTML_SITE. The end tags </body> and </html> rightly belong there.  The idea of XAJAX and AJAX in general is to load the page once only and never have to reload again.

When testMethod() is called its only side effect should be to populate the <div> with the time.

Ed

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.

Re: xajax and __destruct

Okay, I resolved the problem.
I register the method ->testMethod() so xajax create the object CAJAX each time I press the button, but only to call the registered method.
But after this the CAJAX object will be destroyed, so xajax get all the output of the destructor.
I'm implementing the obviously well known isAjax() function to check the XMLHttpRequest.
If the request comes from AJAX, no output will be made.
Unfortunately with the appropriate changes inside xajax_core.js (oe.Request.add...)
But it works.
Thanks for support.

Last edited by frameworker (2010-03-03 9:10:01 PM)

Re: xajax and __destruct

Well, OK but I still feel that the page construction all belongs in the same class...


The function $xajax->canProcessRequest() returns true if the current processing is an xajax call or false if this is a page load. Not sure why you need to change anything in xajax.js...

Ed

If you ever stop learning you may as well dig a hole, crawl in and pull the top over yourself.