1 | <?php |
||||||||||
2 | |||||||||||
3 | namespace Nip\Database\Adapters; |
||||||||||
4 | |||||||||||
5 | /** |
||||||||||
6 | * Class MySQLi |
||||||||||
7 | * @package Nip\Database\Adapters |
||||||||||
8 | */ |
||||||||||
9 | class MySQLi extends AbstractAdapter implements AdapterInterface |
||||||||||
10 | { |
||||||||||
11 | protected $connection; |
||||||||||
12 | |||||||||||
13 | /** |
||||||||||
14 | * Connects to MySQL server |
||||||||||
15 | * |
||||||||||
16 | * @param string|boolean $host |
||||||||||
17 | * @param string|boolean $user |
||||||||||
18 | * @param string|boolean $password |
||||||||||
19 | * @param string|boolean $database |
||||||||||
20 | * @param bool $newLink |
||||||||||
21 | * |
||||||||||
22 | * @return resource |
||||||||||
23 | */ |
||||||||||
24 | public function connect($host = false, $user = false, $password = false, $database = false, $newLink = false) |
||||||||||
25 | { |
||||||||||
26 | $this->connection = mysqli_connect($host, $user, $password, $newLink); |
||||||||||
0 ignored issues
–
show
Bug
introduced
by
![]() It seems like
$password can also be of type boolean ; however, parameter $password of mysqli_connect() does only seem to accept null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$host can also be of type boolean ; however, parameter $hostname of mysqli_connect() does only seem to accept null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $newLink of type boolean is incompatible with the type null|string expected by parameter $database of mysqli_connect() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() The call to
mysqli_connect() has too few arguments starting with port .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||||||
27 | |||||||||||
28 | if ($this->connection) { |
||||||||||
29 | if ($this->selectDatabase($database)) { |
||||||||||
30 | return $this->connection; |
||||||||||
0 ignored issues
–
show
|
|||||||||||
31 | } else { |
||||||||||
32 | $message = 'Cannot select database '.$database; |
||||||||||
33 | } |
||||||||||
34 | } else { |
||||||||||
35 | $message = mysqli_error($this->connection); |
||||||||||
0 ignored issues
–
show
$this->connection of type null is incompatible with the type mysqli expected by parameter $mysql of mysqli_error() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||||
36 | } |
||||||||||
37 | |||||||||||
38 | if (!$this->connection) { |
||||||||||
39 | trigger_error($message, E_USER_WARNING); |
||||||||||
0 ignored issues
–
show
It seems like
$message can also be of type null ; however, parameter $message of trigger_error() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||||
40 | } |
||||||||||
41 | } |
||||||||||
42 | |||||||||||
43 | /** |
||||||||||
44 | * @param $database |
||||||||||
45 | * @return bool |
||||||||||
46 | */ |
||||||||||
47 | public function selectDatabase($database) |
||||||||||
48 | { |
||||||||||
49 | return mysqli_select_db($this->connection, $database); |
||||||||||
50 | } |
||||||||||
51 | |||||||||||
52 | /** |
||||||||||
53 | * @param $sql |
||||||||||
54 | * @return bool|\mysqli_result |
||||||||||
55 | */ |
||||||||||
56 | public function query($sql) |
||||||||||
57 | { |
||||||||||
58 | try { |
||||||||||
59 | return mysqli_query($this->connection, $sql); |
||||||||||
60 | } catch (\Exception $e) { |
||||||||||
61 | throw new \Exception($e->getMessage().' for query '.$sql, $e->getCode(), $e); |
||||||||||
62 | } |
||||||||||
63 | } |
||||||||||
64 | |||||||||||
65 | /** |
||||||||||
66 | * @return int|string |
||||||||||
67 | */ |
||||||||||
68 | public function lastInsertID() |
||||||||||
69 | { |
||||||||||
70 | return mysqli_insert_id($this->connection); |
||||||||||
71 | } |
||||||||||
72 | |||||||||||
73 | /** |
||||||||||
74 | * @return int |
||||||||||
75 | */ |
||||||||||
76 | public function affectedRows() |
||||||||||
77 | { |
||||||||||
78 | return mysqli_affected_rows($this->connection); |
||||||||||
0 ignored issues
–
show
|
|||||||||||
79 | } |
||||||||||
80 | |||||||||||
81 | /** |
||||||||||
82 | * @return string |
||||||||||
83 | */ |
||||||||||
84 | public function info() |
||||||||||
85 | { |
||||||||||
86 | return mysqli_info($this->connection); |
||||||||||
87 | } |
||||||||||
88 | |||||||||||
89 | /** |
||||||||||
90 | * @param $result |
||||||||||
91 | * @return null|object |
||||||||||
92 | */ |
||||||||||
93 | public function fetchObject($result) |
||||||||||
94 | { |
||||||||||
95 | return mysqli_fetch_object($result); |
||||||||||
96 | } |
||||||||||
97 | |||||||||||
98 | /** |
||||||||||
99 | * @param $result |
||||||||||
100 | * @param $row |
||||||||||
101 | * @param $field |
||||||||||
102 | * @return mixed |
||||||||||
103 | */ |
||||||||||
104 | public function result($result, $row, $field) |
||||||||||
105 | { |
||||||||||
106 | return mysqli_result($result, $row, $field); |
||||||||||
0 ignored issues
–
show
The function
mysqli_result was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||||
107 | } |
||||||||||
108 | |||||||||||
109 | /** |
||||||||||
110 | * @param $result |
||||||||||
111 | */ |
||||||||||
112 | public function freeResults($result) |
||||||||||
113 | { |
||||||||||
114 | return mysqli_free_result($result); |
||||||||||
0 ignored issues
–
show
Are you sure the usage of
mysqli_free_result($result) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||||||
115 | } |
||||||||||
116 | |||||||||||
117 | /** |
||||||||||
118 | * @param $table |
||||||||||
119 | * @return array|false |
||||||||||
120 | */ |
||||||||||
121 | public function describeTable($table) |
||||||||||
122 | { |
||||||||||
123 | if (!($this->connection instanceof \mysqli)) { |
||||||||||
124 | return false; |
||||||||||
125 | } |
||||||||||
126 | |||||||||||
127 | $return = ['fields' => [], 'indexes' => []]; |
||||||||||
128 | |||||||||||
129 | $result = $this->execute('DESCRIBE '.$table); |
||||||||||
130 | if (is_bool($result)) { |
||||||||||
131 | return false; |
||||||||||
132 | } |
||||||||||
133 | if (mysqli_num_rows($result)) { |
||||||||||
134 | while ($row = $this->fetchAssoc($result)) { |
||||||||||
135 | $return['fields'][$row['Field']] = [ |
||||||||||
136 | 'field' => $row['Field'], |
||||||||||
137 | 'type' => $row['Type'], |
||||||||||
138 | 'nullable' => strtoupper($row['Null']) == 'YES', |
||||||||||
139 | 'primary' => ( |
||||||||||
140 | isset($return['indexes']['PRIMARY']['fields'][0]) |
||||||||||
141 | && $return['indexes']['PRIMARY']['fields'][0] == $row['Field'] |
||||||||||
142 | ), |
||||||||||
143 | 'default' => $row['Default'], |
||||||||||
144 | 'auto_increment' => ($row['Extra'] === 'auto_increment'), |
||||||||||
145 | ]; |
||||||||||
146 | } |
||||||||||
147 | } |
||||||||||
148 | |||||||||||
149 | $result = $this->execute('SHOW INDEX IN '.$table); |
||||||||||
150 | if (is_bool($result)) { |
||||||||||
151 | return false; |
||||||||||
152 | } |
||||||||||
153 | if (mysqli_num_rows($result)) { |
||||||||||
154 | while ($row = $this->fetchAssoc($result)) { |
||||||||||
155 | if (!isset($return['indexes'][$row['Key_name']])) { |
||||||||||
156 | $return['indexes'][$row['Key_name']] = []; |
||||||||||
157 | } |
||||||||||
158 | $return['indexes'][$row['Key_name']]['fields'][] = $row['Column_name']; |
||||||||||
159 | $return['indexes'][$row['Key_name']]['unique'] = $row['Non_unique'] == '0'; |
||||||||||
160 | $return['indexes'][$row['Key_name']]['fulltext'] = $row['Index_type'] == 'FULLTEXT'; |
||||||||||
161 | $return['indexes'][$row['Key_name']]['type'] = $row['Index_type']; |
||||||||||
162 | } |
||||||||||
163 | } |
||||||||||
164 | |||||||||||
165 | return $return; |
||||||||||
166 | } |
||||||||||
167 | |||||||||||
168 | /** |
||||||||||
169 | * @param $result |
||||||||||
170 | * @return array|null |
||||||||||
171 | */ |
||||||||||
172 | public function fetchAssoc($result) |
||||||||||
173 | { |
||||||||||
174 | return mysqli_fetch_assoc($result); |
||||||||||
175 | } |
||||||||||
176 | |||||||||||
177 | /** |
||||||||||
178 | * @return array |
||||||||||
179 | */ |
||||||||||
180 | public function getTables() |
||||||||||
181 | { |
||||||||||
182 | $return = []; |
||||||||||
183 | |||||||||||
184 | $result = $this->execute("SHOW FULL TABLES"); |
||||||||||
185 | if ($this->numRows($result)) { |
||||||||||
186 | while ($row = $this->fetchArray($result)) { |
||||||||||
187 | $return[$row[0]] = [ |
||||||||||
188 | "type" => $row[1] == "BASE TABLE" ? "table" : "view", |
||||||||||
189 | ]; |
||||||||||
190 | } |
||||||||||
191 | } |
||||||||||
192 | |||||||||||
193 | return $return; |
||||||||||
194 | } |
||||||||||
195 | |||||||||||
196 | /** |
||||||||||
197 | * @param $result |
||||||||||
198 | 3 | * @return int |
|||||||||
199 | */ |
||||||||||
200 | 3 | public function numRows($result) |
|||||||||
201 | 3 | { |
|||||||||
202 | return mysqli_num_rows($result); |
||||||||||
0 ignored issues
–
show
|
|||||||||||
203 | } |
||||||||||
204 | |||||||||||
205 | /** |
||||||||||
206 | * @param $result |
||||||||||
207 | * @return array|null |
||||||||||
208 | */ |
||||||||||
209 | public function fetchArray($result) |
||||||||||
210 | { |
||||||||||
211 | return mysqli_fetch_array($result); |
||||||||||
212 | } |
||||||||||
213 | |||||||||||
214 | /** |
||||||||||
215 | * @param $value |
||||||||||
216 | * @return int|string |
||||||||||
217 | */ |
||||||||||
218 | public function quote($value) |
||||||||||
219 | { |
||||||||||
220 | $value = $this->cleanData($value); |
||||||||||
221 | |||||||||||
222 | return is_numeric($value) ? $value : "'$value'"; |
||||||||||
223 | } |
||||||||||
224 | |||||||||||
225 | /** |
||||||||||
226 | * @param $data |
||||||||||
227 | * @return string |
||||||||||
228 | */ |
||||||||||
229 | public function cleanData($data) |
||||||||||
230 | { |
||||||||||
231 | return mysqli_real_escape_string($this->connection, $data); |
||||||||||
232 | } |
||||||||||
233 | |||||||||||
234 | /** |
||||||||||
235 | * @return string |
||||||||||
236 | */ |
||||||||||
237 | public function error() |
||||||||||
238 | { |
||||||||||
239 | return mysqli_error($this->connection); |
||||||||||
240 | } |
||||||||||
241 | |||||||||||
242 | public function disconnect() |
||||||||||
243 | { |
||||||||||
244 | mysqli_close($this->connection); |
||||||||||
245 | } |
||||||||||
246 | } |
||||||||||
247 |