callback & exception & unset

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
pavel80
Člen | 9
+
0
-

Zdravim!

řeším problém při vyvolání vyjímky v zavolané callback, viz nasledujici kod:

<?php
  class A
  {
    public $callback;

    public function __construct()
    {
      echo "-- construct A\n";
    }

    public function action()
    {
      echo "-- action A\n";
      call_user_func_array($this -> callback, array());
    }

    public function __destruct()
    {
      $this -> callback = NULL;
      echo "-- destruct A\n";
    }
  }


  class B
  {
    public function __construct()
    {
      echo "-- construct B\n";
    }

    public function doAction()
    {
      echo "-- doAction B\n";
      throw new Exception('Exception'); // simulujeme chybu => exception
    }

    public function __destruct()
    {
      echo "-- destruct B\n";
    }
  }


  try {
    $b = new B();

    $a = new A();
    $a -> callback = array($b, 'doAction');
    $a -> action();
  }
  catch (Exception $e) {
    echo "-- catch exception\n";
  }

  echo "\n\n-- unset\n";

  unset($a);
  unset($b);

  echo "\n\n-- done\n";
?>

v případě že doAction() proběhne ok (zakomentovat throw new exc…) je vse ok, tj:

<?php
-- construct B
-- construct A
-- action A
-- doAction B
-- unset
-- destruct A
-- destruct B
-- done
?>

ovšem v případě vyvolání exception to vypadá takto:

<?php
-- construct B
-- construct A
-- action A
-- doAction B
-- catch exception
-- unset
-- destruct A
-- done
-- destruct B
?>

zaráží mě ten destruct až nazávěr, kdy se program ukončí. očekával bych že oba případy budou stejuné a že dojde k destrukci objektů v monentě volání unset, ale to se nestane. ptám se tedy proč? můžete mi něko poradit co stím nebo jak to řešit jinak?

díky
Pavel

jansfabik
Člen | 193
+
0
-

Je to tím, že když vytvoříš instanci třídy Exception, tak se do jejího stack trace uloží reference na tu instanci třídy B. Můžeš to vyřešit tím, že dáš do catch bloku unset($e);.

pavel80
Člen | 9
+
0
-

Diky, něco podobneho mně napadlo ale už mi necvaklo že to trčí v exception. Je vubec možne v PHP zjisit aktivni instance objektů, aby byla jistota že nezustalo někde něco trčet?

Filip Procházka
Moderator | 4668
+
0
-

To přece dělá garbage collector