Completed
Push — master ( 2b3e47...80c358 )
by Nazar
04:57
created

MySQLi::free()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.1481

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 6
cp 0.6667
crap 2.1481
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\DB;
9
use
10
	mysqli_result;
11
12
class MySQLi extends _Abstract {
13
	/**
14
	 * @var \MySQLi Instance of DB connection
15
	 */
16
	protected $instance;
17
	/**
18
	 * @inheritdoc
19
	 */
20 24
	public function __construct ($database, $user = '', $password = '', $host = 'localhost', $prefix = '') {
21 24
		$start = microtime(true);
22
		/**
23
		 * Parsing of $host variable, detecting port and persistent connection
24
		 */
25 24
		list($host, $port) = $this->get_host_and_port($host);
26 24
		$this->instance = new \MySQLi($host, $user, $password, $database, $port);
27 24
		if (!is_object($this->instance) || $this->instance->connect_errno) {
28 1
			return;
29
		}
30 24
		$this->database = $database;
31
		/**
32
		 * Changing DB charset if necessary
33
		 */
34 24
		if ($this->instance->character_set_name() != 'utf8mb4') {
35 24
			$this->instance->set_charset('utf8mb4');
36
		}
37
		/**
38
		 * Force strict mode
39
		 */
40 24
		$this->instance->query(
41 24
			"SET SESSION sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'"
42
		);
43 24
		$this->connected       = true;
44 24
		$this->connecting_time = microtime(true) - $start;
45 24
		$this->db_type         = 'mysql';
46 24
		$this->prefix          = $prefix;
47 24
	}
48
	/**
49
	 * Parse host string into host and port separately
50
	 *
51
	 * Understands `p:` prefix for persistent connections
52
	 *
53
	 * @param string $host_string
54
	 *
55
	 * @return array
56
	 */
57 24
	protected function get_host_and_port ($host_string) {
58 24
		$host = explode(':', $host_string);
59 24
		$port = ini_get('mysqli.default_port') ?: 3306;
60 24
		switch (count($host)) {
61 24
			case 1:
62 24
				$host = $host[0];
63 24
				break;
64 1
			case 2:
65 1
				if ($host[0] == 'p') {
66 1
					$host = "$host[0]:$host[1]";
67
				} else {
68 1
					list($host, $port) = $host;
69
				}
70 1
				break;
71 1
			case 3:
72 1
				$port = $host[2];
73 1
				$host = "$host[0]:$host[1]";
74
		}
75 24
		return [$host, $port];
76
	}
77
	/**
78
	 * @inheritdoc
79
	 *
80
	 * @return bool|mysqli_result
81
	 */
82 24
	protected function q_internal ($query, $parameters = []) {
83 24
		if (!$query) {
84 1
			return false;
85
		}
86 24
		$result = $this->q_internal_internal($query, $parameters);
87
		/*
88
		 * In case of MySQL Client error try once again
89
		 */
90
		if (
91 24
			!$result &&
92 24
			$this->instance->errno >= 2000 &&
93 24
			$this->instance->ping()
94
		) {
95
			$result = $this->q_internal_internal($query, $parameters);
96
		}
97 24
		return $result;
98
	}
99
	/**
100
	 * @param string $query
101
	 * @param array  $parameters
102
	 *
103
	 * @return bool|mysqli_result
104
	 */
105 24
	protected function q_internal_internal ($query, $parameters) {
106 24
		if (!$parameters) {
107 24
			return $this->instance->query($query);
108
		}
109 21
		$stmt = $this->instance->prepare($query);
110 21
		if (!$stmt) {
111
			return false;
112
		}
113
		// Allows to provide more parameters for prepared statements than needed
114 21
		$local_parameters = array_slice($parameters, 0, substr_count($query, '?'));
115 21
		$stmt->bind_param(
116 21
			str_repeat('s', count($local_parameters)),
117 21
			...$local_parameters
118
		);
119 21
		$result = $stmt->execute();
120
		/**
121
		 * Return result only for SELECT queries, boolean otherwise
122
		 */
123 21
		return $stmt->get_result() ?: $result;
124
	}
125
	/**
126
	 * @inheritdoc
127
	 *
128
	 * @param false|mysqli_result $query_result
129
	 */
130 23
	public function f ($query_result, $single_column = false, $array = false, $indexed = false) {
131 23
		if (!($query_result instanceof mysqli_result)) {
132 1
			return false;
133
		}
134 23
		$result_type = $single_column || $indexed ? MYSQLI_NUM : MYSQLI_ASSOC;
135 23
		if ($array) {
136 20
			$result = [];
137 20
			while ($current = $query_result->fetch_array($result_type)) {
138 20
				$result[] = $single_column ? $current[0] : $current;
139
			}
140 20
			$this->free($query_result);
141 20
			return $result;
142
		}
143 22
		$result = $query_result->fetch_array($result_type);
144 22
		if ($result === null) {
145 16
			$result = false;
146
		}
147 22
		return $single_column && $result ? $result[0] : $result;
148
	}
149
	/**
150
	 * @inheritdoc
151
	 */
152 17
	public function id () {
153 17
		return $this->instance->insert_id;
154
	}
155
	/**
156
	 * @inheritdoc
157
	 */
158 1
	public function affected () {
159 1
		return $this->instance->affected_rows;
160
	}
161
	/**
162
	 * @inheritdoc
163
	 *
164
	 * @param false|mysqli_result $query_result
165
	 */
166 20
	public function free ($query_result) {
167 20
		if ($query_result instanceof mysqli_result) {
168 20
			$query_result->free();
169
		}
170 20
		return true;
171
	}
172
	/**
173
	 * @inheritdoc
174
	 */
175 2
	public function columns ($table, $like = false) {
176 2
		if (!$table) {
177 1
			return false;
178
		}
179 2
		if ($like) {
180 1
			$like    = $this->s($like);
181 1
			$columns = $this->qfas("SHOW COLUMNS FROM `$table` LIKE $like") ?: [];
182
		} else {
183 2
			$columns = $this->qfas("SHOW COLUMNS FROM `$table`") ?: [];
184
		}
185 2
		return $columns;
186
	}
187
	/**
188
	 * @inheritdoc
189
	 */
190 1
	public function tables ($like = false) {
191 1
		if ($like) {
192 1
			$like = $this->s($like);
193 1
			return $this->qfas("SHOW TABLES FROM `$this->database` LIKE $like") ?: [];
194
		} else {
195 1
			return $this->qfas("SHOW TABLES FROM `$this->database`") ?: [];
196
		}
197
	}
198
	/**
199
	 * @inheritdoc
200
	 */
201 22
	protected function s_internal ($string, $single_quotes_around) {
202 22
		$return = $this->instance->real_escape_string($string);
203 22
		return $single_quotes_around ? "'$return'" : $return;
204
	}
205
	/**
206
	 * @inheritdoc
207
	 */
208 1
	public function server () {
209 1
		return $this->instance->server_info;
210
	}
211
	/**
212
	 * @inheritdoc
213
	 */
214 2
	public function __destruct () {
215 2
		if ($this->connected && is_object($this->instance)) {
216 2
			$this->instance->close();
217 2
			$this->connected = false;
218
		}
219 2
	}
220
}
221