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?
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();
?>Kiitoksia tää selvensi asioita.
Aihe on jo aika vanha, joten et voi enää vastata siihen.