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