Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: destruct ja latauksen keskeytys

zamu [15.01.2008 15:28:06]

#

Muistelin, että luin jostain, että php-tiedoston suoritus loppuu jos selaimesta painaa peruuta tai latausen lopetusta. Joten kysyn onko tämä totta?
Ja jos tämä on totta, niin pysähtyykö php-koodin suoritus juuri siihen mihin se peruutuksen sattuessa on ehtinyt suorittaa, vai suorittaako se mahdollisen silmukan loppuun ensiksi?

Ja varsinainen kysymykseni: Mikäli tuhon ensimmäiseen vastaukseen on myönteinen vastaus ja ollaan luotu oli jossa on __destruct() functio, niin suoritetaanko tämä functio silti. Sillä mikäli jos olen ymmärtänyt __destruct():n oikein se suoritetaan aina kun olio "tuhoutuu". Eli käytännössä silloin, kun tiedoston käsittely loppuu?

tsuriga [15.01.2008 20:38:51]

#

Näitähän voi toki testailla itse kukin. Mielenkiintoisia kysymyksiä, ja varsinkin mielenkiintoisia tuloksia sain testaillessani:
-Apassi ajoi asetuksista huolimatta tiedostoa aina niin pitkään kunnes oltiin saavutettu ajon aikarajoitus.
-Olion __destruct metodia ei kutsuta ilman sen rekisteröimistä shutdown-funkkariksi.
-Ilmeisesti tuota silmukkaa ei suoriteta loppuun.
-sleep ja usleep ohittavat aikarajoituksen.

Jotain vähän haeskelinkin Intternetsistä, ja siellä lausuttihin: PHP ei tiedä käyttäjän lopettaneen suorituksen ennen kuin se yrittää tulostaa jotain.

Tässäpä koodi, jolla testailin

<?php

class Test
{

    // koska shutdownissa cwdir vaihtuu serverroottiin
    const ABSOLUTE_LOGPATH = 'C:/Apache/htdocs/';
###
    // muokkaile näitä mahdollisesti erilaisten tulosten saavuttamiseksi
    const IGNORE_ABORT = false;
    const REGISTER_SHUTDOWN = true;
    const OB_ON = true;
    const TIME_LIMIT = 6; // s
    const NAPTIME = 1000000; // µs ('mikrosekunneissa', jos mikromerkki ei näy oikein)
    const LONGNAP = 6; // s, muokkaile lyhemmäksi kuin TIME_LIMIT jos tahdot looppailla
###

    private $_round;
    private $_timer;

    public function __construct()
    {
        ignore_user_abort( self::IGNORE_ABORT );
        // ilman tätä tuota tuhoamisfunkkaria ei jostakin syystä kutsuta.. hmm
        if ( self::REGISTER_SHUTDOWN )
            register_shutdown_function( array( &$this, '__destruct' ) );
        echo 'Test instance initialized!<br />';
        $this->_round = -1;
        $this->_timer = microtime( true );
    }


    public function run()
    {
        file_put_contents( 'test.log', '' );
        set_time_limit( self::TIME_LIMIT );
        if ( self::OB_ON )
            ob_start();
        while( true ):
            $this->_round += 2;
            $str = ' this is round ' . $this->_round . ' in the loop';
            echo '(Looping) ', $str, '<br />';
            if ( self::OB_ON )
                ob_flush();
            file_put_contents(
                               'test.log',
                               '(Archiving)' . $str . "\n",
                               FILE_APPEND
                             );
            usleep( self::NAPTIME );
            $round = $this->_round;
            $this->_round = 'Roundcounter is sleepy +_+';
            usleep( self::LONGNAP );
            $this->_round = $round - 1;
        endwhile;
    }

    public function __destruct()
    {
        if ( self::OB_ON )
            ob_end_clean();
        $msg = '(Destructing) Ran through ' . $this->_round . ' loops' . "\n";
        $msg .= '(Execution time) ' . ( microtime( true ) - $this->_timer );
        file_put_contents(
                           self::ABSOLUTE_LOGPATH . 'test.log',
                           $msg,
                           FILE_APPEND
                         );
        echo 'Destroying Test instance!';
    }
}

$test = new Test();
$test->run();

?>

zamu [18.01.2008 12:32:31]

#

Kiitoksia tää selvensi asioita.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta