1--TEST--
2Ensure type hints are enforced for functions invoked as callbacks.
3--FILE--
4<?php
5  set_error_handler('myErrorHandler', E_RECOVERABLE_ERROR);
6  function myErrorHandler($errno, $errstr, $errfile, $errline) {
7      echo "$errno: $errstr - $errfile($errline)\n";
8      return true;
9  }
10
11  echo "---> Type hints with callback function:\n";
12  class A  {  }
13  function f1(A $a)  {
14      echo "in f1;\n";
15  }
16  function f2(A $a = null)  {
17      echo "in f2;\n";
18  }
19  call_user_func('f1', 1);
20  call_user_func('f1', new A);
21  call_user_func('f2', 1);
22  call_user_func('f2');
23  call_user_func('f2', new A);
24  call_user_func('f2', null);
25
26
27  echo "\n\n---> Type hints with callback static method:\n";
28  class C {
29      static function f1(A $a) {
30          if (isset($this)) {
31              echo "in C::f1 (instance);\n";
32          } else {
33              echo "in C::f1 (static);\n";
34          }
35      }
36      static function f2(A $a = null) {
37          if (isset($this)) {
38              echo "in C::f2 (instance);\n";
39          } else {
40              echo "in C::f2 (static);\n";
41          }
42      }
43  }
44  call_user_func(array('C', 'f1'), 1);
45  call_user_func(array('C', 'f1'), new A);
46  call_user_func(array('C', 'f2'), 1);
47  call_user_func(array('C', 'f2'));
48  call_user_func(array('C', 'f2'), new A);
49  call_user_func(array('C', 'f2'), null);
50
51
52  echo "\n\n---> Type hints with callback instance method:\n";
53  class D {
54      function f1(A $a) {
55          if (isset($this)) {
56              echo "in C::f1 (instance);\n";
57          } else {
58              echo "in C::f1 (static);\n";
59          }
60      }
61      function f2(A $a = null) {
62          if (isset($this)) {
63              echo "in C::f2 (instance);\n";
64          } else {
65              echo "in C::f2 (static);\n";
66          }
67      }
68  }
69  $d = new D;
70  call_user_func(array($d, 'f1'), 1);
71  call_user_func(array($d, 'f1'), new A);
72  call_user_func(array($d, 'f2'), 1);
73  call_user_func(array($d, 'f2'));
74  call_user_func(array($d, 'f2'), new A);
75  call_user_func(array($d, 'f2'), null);
76
77?>
78--EXPECTF--
79---> Type hints with callback function:
804096: Argument 1 passed to f1() must be an instance of A, integer given%s(10)
81in f1;
82in f1;
834096: Argument 1 passed to f2() must be an instance of A, integer given%s(13)
84in f2;
85in f2;
86in f2;
87in f2;
88
89
90---> Type hints with callback static method:
914096: Argument 1 passed to C::f1() must be an instance of A, integer given%s(26)
92in C::f1 (static);
93in C::f1 (static);
944096: Argument 1 passed to C::f2() must be an instance of A, integer given%s(33)
95in C::f2 (static);
96in C::f2 (static);
97in C::f2 (static);
98in C::f2 (static);
99
100
101---> Type hints with callback instance method:
1024096: Argument 1 passed to D::f1() must be an instance of A, integer given%s(51)
103in C::f1 (instance);
104in C::f1 (instance);
1054096: Argument 1 passed to D::f2() must be an instance of A, integer given%s(58)
106in C::f2 (instance);
107in C::f2 (instance);
108in C::f2 (instance);
109in C::f2 (instance);
110