1--TEST--
2MySQL PDOStatement->bindParam()
3--EXTENSIONS--
4pdo_mysql
5--SKIPIF--
6<?php
7require_once __DIR__ . '/inc/mysql_pdo_test.inc';
8MySQLPDOTest::skip();
9?>
10--FILE--
11<?php
12    require_once __DIR__ . '/inc/mysql_pdo_test.inc';
13    $db = MySQLPDOTest::factory();
14    $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
15
16    $table = 'pdo_mysql_stmt_bindparam';
17    MySQLPDOTest::createTestTable($table, $db);
18
19    function pdo_mysql_stmt_bindparam($db, $offset) {
20        global $table;
21
22        $stmt = $db->prepare("SELECT id, label FROM {$table} WHERE id > ? ORDER BY id ASC LIMIT 2");
23        $in = 0;
24        if (!$stmt->bindParam(1, $in))
25            printf("[%03d + 1] Cannot bind parameter, %s %s\n", $offset,
26                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
27
28        $stmt->execute();
29        $id = $label = null;
30
31        if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
32            printf("[%03d + 2] Cannot bind integer column, %s %s\n", $offset,
33                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
34
35        if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
36            printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset,
37                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
38
39        while ($stmt->fetch(PDO::FETCH_BOUND))
40            printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
41                $in,
42                var_export($id, true), gettype($id),
43                var_export($label, true), gettype($label));
44
45        printf("Same again...\n");
46        $stmt->execute();
47        while ($stmt->fetch(PDO::FETCH_BOUND))
48            printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
49                $in,
50                var_export($id, true), gettype($id),
51                var_export($label, true), gettype($label));
52
53        // NULL values
54        printf("NULL...\n");
55        $stmt = $db->prepare("INSERT INTO {$table}(id, label) VALUES (100, ?)");
56        $label = null;
57        if (!$stmt->bindParam(1, $label))
58            printf("[%03d + 4] Cannot bind parameter, %s %s\n", $offset,
59                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
60
61        if (!$stmt->execute())
62            printf("[%03d + 5] Cannot execute statement, %s %s\n", $offset,
63                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
64
65        /* NOTE: you cannot use PDO::query() with unbuffered, native PS - see extra test */
66        $stmt = $db->prepare("SELECT id, NULL AS _label FROM {$table} WHERE label IS NULL");
67        $stmt->execute();
68
69        $id = $label = 'bogus';
70        if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
71            printf("[%03d + 6] Cannot bind NULL column, %s %s\n", $offset,
72                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
73
74        if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
75            printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset,
76                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
77
78        while ($stmt->fetch(PDO::FETCH_BOUND))
79            printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
80                $in,
81                var_export($id, true), gettype($id),
82                var_export($label, true), gettype($label));
83    }
84
85    try {
86        printf("Emulated PS...\n");
87        $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
88        if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
89            printf("[002] Unable to turn on emulated prepared statements\n");
90
91        printf("Buffered...\n");
92        $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
93        pdo_mysql_stmt_bindparam($db, 3);
94
95        printf("Unbuffered...\n");
96        MySQLPDOTest::createTestTable($table, $db);
97        $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
98        pdo_mysql_stmt_bindparam($db, 4);
99
100        printf("Native PS...\n");
101        $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
102        if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
103            printf("[004] Unable to turn off emulated prepared statements\n");
104
105        printf("Buffered...\n");
106        MySQLPDOTest::createTestTable($table, $db);
107        $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
108        pdo_mysql_stmt_bindparam($db, 5);
109
110        printf("Unbuffered...\n");
111        MySQLPDOTest::createTestTable($table, $db);
112        $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
113        pdo_mysql_stmt_bindparam($db, 6);
114
115    } catch (PDOException $e) {
116        printf("[001] %s [%s] %s\n",
117            $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
118    }
119
120    print "done!";
121?>
122--CLEAN--
123<?php
124require_once __DIR__ . '/inc/mysql_pdo_test.inc';
125$db = MySQLPDOTest::factory();
126$db->exec('DROP TABLE IF EXISTS pdo_mysql_stmt_bindparam');
127?>
128--EXPECT--
129Emulated PS...
130Buffered...
131in = 0 -> id = 1 (integer) / label = 'a' (string)
132in = 0 -> id = 2 (integer) / label = 'b' (string)
133Same again...
134in = 0 -> id = 1 (integer) / label = 'a' (string)
135in = 0 -> id = 2 (integer) / label = 'b' (string)
136NULL...
137in = 0 -> id = 100 (integer) / label = NULL (NULL)
138Unbuffered...
139in = 0 -> id = 1 (integer) / label = 'a' (string)
140in = 0 -> id = 2 (integer) / label = 'b' (string)
141Same again...
142in = 0 -> id = 1 (integer) / label = 'a' (string)
143in = 0 -> id = 2 (integer) / label = 'b' (string)
144NULL...
145in = 0 -> id = 100 (integer) / label = NULL (NULL)
146Native PS...
147Buffered...
148in = 0 -> id = 1 (integer) / label = 'a' (string)
149in = 0 -> id = 2 (integer) / label = 'b' (string)
150Same again...
151in = 0 -> id = 1 (integer) / label = 'a' (string)
152in = 0 -> id = 2 (integer) / label = 'b' (string)
153NULL...
154in = 0 -> id = 100 (integer) / label = NULL (NULL)
155Unbuffered...
156in = 0 -> id = 1 (integer) / label = 'a' (string)
157in = 0 -> id = 2 (integer) / label = 'b' (string)
158Same again...
159in = 0 -> id = 1 (integer) / label = 'a' (string)
160in = 0 -> id = 2 (integer) / label = 'b' (string)
161NULL...
162in = 0 -> id = 100 (integer) / label = NULL (NULL)
163done!
164