1--TEST--
2A SensitiveParameterValue keeps inner objects alive.
3--FILE--
4<?php
5
6class CustomDestructor
7{
8  public function __construct(private int $id)
9  {
10    echo __METHOD__, " - ", $this->id, PHP_EOL;
11  }
12
13  public function __destruct()
14  {
15    echo __METHOD__, " - ", $this->id, PHP_EOL;
16  }
17
18  public function getId(): int
19  {
20    return $this->id;
21  }
22}
23
24function test(#[SensitiveParameter] CustomDestructor $o, bool $throw)
25{
26  if ($throw) {
27    throw new Exception('Error');
28  }
29}
30
31function wrapper(int $id, bool $throw)
32{
33  $o = new CustomDestructor($id);
34  test($o, $throw);
35}
36
37function main(): SensitiveParameterValue
38{
39  try {
40    echo "Before 1", PHP_EOL;
41    wrapper(1, false);
42    echo "After 1", PHP_EOL;
43    echo "Before 2", PHP_EOL;
44    wrapper(2, true);
45    echo "Not Reached: After 2", PHP_EOL;
46  } catch (Exception $e) {
47    echo "catch", PHP_EOL;
48    return $e->getTrace()[0]['args'][0];
49  }
50}
51
52$v = main();
53
54var_dump($v->getValue()->getId());
55
56echo "Before unset", PHP_EOL;
57
58unset($v);
59
60echo "After unset", PHP_EOL;
61
62?>
63--EXPECT--
64Before 1
65CustomDestructor::__construct - 1
66CustomDestructor::__destruct - 1
67After 1
68Before 2
69CustomDestructor::__construct - 2
70catch
71int(2)
72Before unset
73CustomDestructor::__destruct - 2
74After unset
75