1--TEST--
2Interface of the class mysqli_stmt
3--SKIPIF--
4<?php
5	require_once('skipif.inc');
6	require_once('skipifemb.inc');
7	require_once('skipifconnectfailure.inc');
8?>
9--FILE--
10<?php
11	require('connect.inc');
12	require('table.inc');
13
14	$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
15	$stmt = new mysqli_stmt($link);
16
17	printf("Parent class:\n");
18	var_dump(get_parent_class($stmt));
19
20	printf("\nMethods:\n");
21
22	$methods = get_class_methods($stmt);
23	$expected_methods = array(
24		'__construct'       => true,
25		'attr_get'          => true,
26		'attr_set'          => true,
27		'bind_param'        => true,
28		'bind_result'       => true,
29		'close'             => true,
30		'data_seek'         => true,
31		'execute'           => true,
32		'fetch'             => true,
33		'free_result'       => true,
34		'get_warnings'      => true,
35		'num_rows'          => true,
36		'prepare'           => true,
37		'reset'             => true,
38		'result_metadata'   => true,
39		'send_long_data'    => true,
40		'store_result'      => true,
41	);
42
43	if ($IS_MYSQLND) {
44		$expected_methods['get_result'] = true;
45		$expected_methods['more_results'] = true;
46		$expected_methods['next_result'] = true;
47	}
48
49	foreach ($methods as $k => $method) {
50	if (isset($expected_methods[$method])) {
51		unset($methods[$k]);
52		unset($expected_methods[$method]);
53	}
54		if ($method == 'mysqli_stmt') {
55			// get_class_method reports different constructor names
56			unset($expected_methods['__construct']);
57			unset($methods[$k]);
58		}
59	}
60	if (!empty($methods)) {
61		printf("More methods found than indicated. Dumping list of unexpected methods.\n");
62		var_dump($methods);
63	}
64	if (!empty($expected_methods)) {
65		printf("Some methods are missing. Dumping list of missing methods.\n");
66		var_dump($expected_methods);
67	}
68	if (empty($methods) && empty($expected_methods))
69		printf("ok\n");
70
71	printf("\nClass variables:\n");
72	$variables = array_keys(get_class_vars(get_class($stmt)));
73	sort($variables);
74	foreach ($variables as $k => $var)
75		printf("%s\n", $var);
76
77	printf("\nObject variables:\n");
78	$variables = array_keys(get_object_vars($stmt));
79	foreach ($variables as $k => $var)
80		printf("%s\n", $var);
81
82printf("\nMagic, magic properties:\n");
83
84assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows);
85printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows);
86
87if (!$stmt->prepare("INSERT INTO test(id, label) VALUES (100, 'z')") ||
88!$stmt->execute())
89printf("[001] [%d] %s\n", $stmt->errno, $stmt->error);
90
91assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows);
92printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows);
93
94assert(mysqli_stmt_errno($stmt) === $stmt->errno);
95printf("stmt->errno = '%s'\n", $stmt->errno);
96
97assert(mysqli_stmt_error($stmt) === $stmt->error);
98printf("stmt->error = '%s'\n", $stmt->error);
99
100assert(mysqli_stmt_field_count($stmt) === $stmt->field_count);
101printf("stmt->field_count = '%s'\n", $stmt->field_count);
102
103assert($stmt->id > 0);
104printf("stmt->id = '%s'\n", $stmt->id);
105
106assert(mysqli_stmt_insert_id($stmt) === $stmt->insert_id);
107printf("stmt->insert_id = '%s'\n", $stmt->insert_id);
108
109assert(mysqli_stmt_num_rows($stmt) === $stmt->num_rows);
110printf("stmt->num_rows = '%s'\n", $stmt->num_rows);
111
112assert(mysqli_stmt_param_count($stmt) === $stmt->param_count);
113printf("stmt->param_count = '%s'\n", $stmt->param_count);
114
115assert(mysqli_stmt_sqlstate($stmt) === $stmt->sqlstate);
116printf("stmt->sqlstate = '%s'\n", $stmt->sqlstate);
117
118printf("\nAccess to undefined properties:\n");
119printf("stmt->unknown = '%s'\n", @$stmt->unknown);
120@$stmt->unknown = 13;
121printf("stmt->unknown = '%s'\n", @$stmt->unknown);
122
123printf("\nPrepare using the constructor:\n");
124$stmt = new mysqli_stmt($link, 'SELECT id FROM test ORDER BY id');
125if (!$stmt->execute())
126printf("[002] [%d] %s\n", $stmt->errno, $stmt->error);
127$stmt->close();
128
129$obj = new stdClass();
130if (!is_object($stmt = new mysqli_stmt($link, $obj)))
131printf("[003] Expecting NULL got %s/%s\n", gettype($stmt), $stmt);
132
133print "done!";
134?>
135--EXPECTF--
136Parent class:
137bool(false)
138
139Methods:
140ok
141
142Class variables:
143affected_rows
144errno
145error
146field_count
147id
148insert_id
149num_rows
150param_count
151sqlstate
152
153Object variables:
154affected_rows
155insert_id
156num_rows
157param_count
158field_count
159errno
160error
161sqlstate
162id
163
164Magic, magic properties:
165
166Warning: mysqli_stmt_affected_rows(): invalid object or resource mysqli_stmt
167 in %s on line %d
168
169Warning: main(): Property access is not allowed yet in %s on line %d
170
171Warning: main(): Property access is not allowed yet in %s on line %d
172stmt->affected_rows = ''
173stmt->affected_rows = '1'
174stmt->errno = '0'
175stmt->error = ''
176stmt->field_count = '0'
177stmt->id = '%d'
178stmt->insert_id = '0'
179stmt->num_rows = '0'
180stmt->param_count = '0'
181stmt->sqlstate = '00000'
182
183Access to undefined properties:
184stmt->unknown = ''
185stmt->unknown = '13'
186
187Prepare using the constructor:
188
189Warning: mysqli_stmt::__construct() expects parameter 2 to be %binary_string_optional%, object given in %s on line %d
190done!