1--TEST--
2Pdo\Pgsql::setNoticeCallback() use F ZPP for trampoline callback and does not leak
3--EXTENSIONS--
4pdo_pgsql
5--SKIPIF--
6<?php
7require __DIR__ . '/config.inc';
8require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
9PDOTest::skip();
10?>
11--FILE--
12<?php
13
14require_once __DIR__ . "/config.inc";
15
16$db = new Pdo\Pgsql($config['ENV']['PDOTEST_DSN']);
17
18function disp($message) { echo trim($message)."\n"; }
19function attach($db, $callback)
20{
21    if (is_array($callback) && $callback[0] === null) {
22        $callback = $callback[1];
23        $rc = new ReflectionClass(Pdo\Pgsql::class);
24        $db = $rc->newInstanceWithoutConstructor();
25    }
26    $db->setNoticeCallback($callback);
27}
28
29class T { public function z($m) { echo $m."\n"; } public function __call($m, $p) { echo "bah $m\n"; } }
30$t = new T;
31$rounds = [
32    [ $t, 'disp' ],
33    3, // Error; but then as the old callback is kept, it will be used in the call that follows the caught error.
34    null, // No callback: clear everything.
35    'wouldAnyoneNameAFunctionThisWay', // So this one will crash and *no output will follow*.
36    [ null, [ $t, 'disp' ] ], // Valid callback on an unvalid Pdo.
37    [ $t, 'disp' ],
38];
39require __DIR__ . '/issue78621.inc';
40
41?>
42--EXPECTF--
43bah disp
44Caught TypeError: %s: Argument #1 ($callback) %s
45bah disp
46Caught TypeError: %s: Argument #1 ($callback) %s
47Caught Error: %s object is uninitialized
48bah disp
49array(1) {
50  [0]=>
51  array(1) {
52    ["a"]=>
53    string(2) "oh"
54  }
55}
56Done
57
58