Your location:Tech News>News>Script>__Destruct and order problem in php register_shutdown_function executed

Latest News

__Destruct and order problem in php register_shutdown_function executed

Author:fsadmin

Views:

  According to parse php manual.

  __destruct is

  Destructor references are deleted, or when the object is explicitly destroyed at all to an object.

  And is register_shutdown_function

  Registers a callback to be executed after script execution finishes or exit () is called. Register a callback function to perform this function when the script has finished running or call exit ().

  Literally, __ destruct is the object level, and register_shutdown_function entire script level, should register_shutdown_function higher level, a function that is registered should be executed last.To confirm our hypothesis, we write a script:

  Copy the code code is as follows:

  register_shutdown_function (function () {echo ''global'';});

  class A {

  public function __construct () {

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  new A;

  Results of the:

  Copy the code code is as follows:

  A :: __ destruct

  global

  Fully confirmed our speculation, which in terms of objects -> order of the script being executed..

  But if we register it in the object register_shutdown_function?It is still the same order it?!

  Copy the code code is as follows:

  class A {

  public function __construct () {

  register_shutdown_function (function () {echo ''local'', ''
'';});

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  new A;

  result:

  Copy the code code is as follows:

  local

  A :: __ destruct

  We can see register_shutdown_function first to be called, and finally execution object __destruct.This suggests a method register_shutdown_function function is registered as a class?!Not known, it may need to view the source code to parse the php.

  We can expand the scope of view the situation:

  Copy the code code is as follows:

  register_shutdown_function (function () {echo ''global'', ''
'';});

  class A {

  public function __construct () {

  register_shutdown_function (array ($ this, ''op''));

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  public function op ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  class B {

  public function __construct ()

  {

  register_shutdown_function (array ($ this, ''op''));

  $ Obj = new A;

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  public function op ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  $ B = new B;

  We register register_shutdown_function a global function, class AB, and in a respective register, and there are class destructor.The last run results will happen?

  Copy the code code is as follows:

  global

  B :: op

  A :: op

  A :: __ destruct

  B :: __ destruct

  The results completely subvert our imagination, register_shutdown_function a function of whether or registered in the class registered in the overall situation, it is first executed, the order in which they were registered in the implementation of the order of class.If we carefully study whether global register_shutdown_function function are placed in front of or behind the results, things seem to have the results that register_shutdown_function to perform than __destruct, global register_shutdown_function function and prior to class registration register_shutdown_function first execution.

  Wait a minute, I can not accept this result, according to this conclusion, we say that the script has been completed you can then perform __destruct?!Therefore, I would like to continue to verify this conclusion --- remove class registration register_shutdown_function, while retaining overall register_shutdown_function:

  Copy the code code is as follows:

  class A {

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  class B {

  public function __construct ()

  {

  $ Obj = new A;

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  register_shutdown_function (function () {echo ''global'', ''
'';});

  Output:

  Copy the code code is as follows:

  A :: __ destruct

  global

  B :: __ destruct

  The result was a loss, A, B destructor order of execution of two classes above suspicion, because B is called A, B Class A definitely better than before destruction, but overall register_shutdown_function function and how they are executed in the middle?!Hard to understand.

  According to the analysis sheet, the destructor may be performed when call exit.

  Destructor even when exit () will be called when the script terminated.Call exit destructor () will terminate the operation of the rest of the closing operation.

  If you call exit in a function, they are called and how it?

  Copy the code code is as follows:

  class A {

  public function __construct () {

  register_shutdown_function (array ($ this, ''op''));

  exit;

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  public function op ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  class B {

  public function __construct ()

  {

  register_shutdown_function (array ($ this, ''op''));

  $ Obj = new A;

  }

  public function __destruct ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  public function op ()

  {

  echo __class __, ''::'', __ function__, ''
'';

  }

  }

  register_shutdown_function (function () {echo ''global'', ''
'';});

  $ B = new B;

  Output:

  Copy the code code is as follows:

  global

  B :: op

  A :: op

  B :: __ destruct

  A :: __ destruct

  This sequence is similar to the third example, different and it is inconceivable that the B class destructor performed prior to the class A, B do destruction after all references to class A was only destroyed?!unknown.

  in conclusion:

  1, try not to mix and match in the script that register_shutdown_function and __destruct, their behavior is totally unpredictable.

  1, because the object referenced in each other, we can not sensing when an object is destroyed when it wants to order the content, the content should not be placed in the destructor __destruct;

  2, try not registered in the class register_shutdown_function, because it''s difficult to predict (only registered only function when calling the object), and __destruct can replace register_shutdown_function;

  3, if you need to perform the associated action when the script exits, the best register_shutdown_function registered at the beginning of the script, and all the action in a function where.

  Please correct me.

  You may also be interested in the article: () function to use the example in PHP using php ignore_user_abort depth analysis and register_shutdown_function register_shutdown_function use PHP function PHP function register_shutdown_function register_shutdown_function intercepted fatal error sample PHP error handler register_shutdown_function use the sample php register_shutdown_function Detailed PHP function in register_shutdown_function Based on the introduction and usage of function Detailed

Recommend article

Relate article