Completed
Push — master ( fde6a1...7c16b9 )
by Nazar
04:03
created

MySQLi::f()   B

Complexity

Conditions 10
Paths 45

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 11.8232

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 10
eloc 14
c 1
b 1
f 0
nc 45
nop 4
dl 0
loc 19
ccs 14
cts 19
cp 0.7368
crap 11.8232
rs 7.2765

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 24
		$this->connected       = true;
38 24
		$this->connecting_time = microtime(true) - $start;
39 24
		$this->db_type         = 'mysql';
40 24
		$this->prefix          = $prefix;
41 24
	}
42
	/**
43
	 * Parse host string into host and port separately
44
	 *
45
	 * Understands `p:` prefix for persistent connections
46
	 *
47
	 * @param string $host_string
48
	 *
49
	 * @return array
50
	 */
51 24
	protected function get_host_and_port ($host_string) {
52 24
		$host = explode(':', $host_string);
53 24
		$port = ini_get('mysqli.default_port') ?: 3306;
54 24
		switch (count($host)) {
55 24
			case 1:
56 24
				$host = $host[0];
57 24
				break;
58 1
			case 2:
59 1
				if ($host[0] == 'p') {
60 1
					$host = "$host[0]:$host[1]";
61
				} else {
62 1
					list($host, $port) = $host;
63
				}
64 1
				break;
65 1
			case 3:
66 1
				$port = $host[2];
67 1
				$host = "$host[0]:$host[1]";
68
		}
69 24
		return [$host, $port];
70
	}
71
	/**
72
	 * @inheritdoc
73
	 *
74
	 * @return false|mysqli_result
75
	 */
76 24
	protected function q_internal ($query, $parameters = []) {
77 24
		if (!$query) {
78 1
			return false;
79
		}
80 24
		for ($i = 0; $i < 2; ++$i) {
81 24
			if ($parameters) {
82 1
				$stmt = $this->instance->prepare($query);
83
				// Allows to provide more parameters for prepared statements than needed
84 1
				$local_parameters = array_slice($parameters, 0, substr_count($query, '?'));
85 1
				$stmt->bind_param(
86 1
					str_repeat('s', count($local_parameters)),
87 1
					...$local_parameters
88
				);
89 1
				$stmt->execute();
90 1
				$result = $stmt->get_result();
91
			} else {
92 24
				$result = $this->instance->query($query);
93
			}
94
			// In case of MySQL Client error - try to fix everything, but only once
95
			if (
96 24
				$result ||
97
				$this->instance->errno < 2000 ||
98 24
				!$this->instance->ping()
99
			) {
100 24
				break;
101
			}
102
		}
103
		/** @noinspection PhpUndefinedVariableInspection */
104 24
		return $result;
105
	}
106
	/**
107
	 * @inheritdoc
108
	 *
109
	 * @param false|mysqli_result $query_result
110
	 */
111 23
	public function f ($query_result, $single_column = false, $array = false, $indexed = false) {
112 23
		if (!($query_result instanceof mysqli_result)) {
113 1
			return false;
114
		}
115 23
		$result_type = $single_column || $indexed ? MYSQLI_NUM : MYSQLI_ASSOC;
116 23
		if ($array) {
117 20
			$result = [];
118 20
			while ($current = $query_result->fetch_array($result_type)) {
119 20
				$result[] = $single_column ? $current[0] : $current;
120
			}
121 20
			$this->free($query_result);
122 20
			return $result;
123
		}
124 22
		$result = $query_result->fetch_array($result_type);
125 22
		if ($result === null) {
126 16
			$result = false;
127
		}
128 22
		return $single_column && $result ? $result[0] : $result;
129
	}
130
	/**
131
	 * @inheritdoc
132
	 */
133 17
	public function id () {
134 17
		return $this->instance->insert_id;
135
	}
136
	/**
137
	 * @inheritdoc
138
	 */
139 1
	public function affected () {
140 1
		return $this->instance->affected_rows;
141
	}
142
	/**
143
	 * @inheritdoc
144
	 *
145
	 * @param false|mysqli_result $query_result
146
	 */
147 20
	public function free ($query_result) {
148 20
		if ($query_result instanceof mysqli_result) {
149 20
			$query_result->free();
150
		}
151 20
		return true;
152
	}
153
	/**
154
	 * @inheritdoc
155
	 */
156 2
	public function columns ($table, $like = false) {
157 2
		if (!$table) {
158 1
			return false;
159
		}
160 2
		if ($like) {
161 1
			$like    = $this->s($like);
162 1
			$columns = $this->qfas("SHOW COLUMNS FROM `$table` LIKE $like") ?: [];
163
		} else {
164 2
			$columns = $this->qfas("SHOW COLUMNS FROM `$table`") ?: [];
165
		}
166 2
		return $columns;
167
	}
168
	/**
169
	 * @inheritdoc
170
	 */
171 1
	public function tables ($like = false) {
172 1
		if ($like) {
173 1
			$like = $this->s($like);
174 1
			return $this->qfas("SHOW TABLES FROM `$this->database` LIKE $like") ?: [];
175
		} else {
176 1
			return $this->qfas("SHOW TABLES FROM `$this->database`") ?: [];
177
		}
178
	}
179
	/**
180
	 * @inheritdoc
181
	 */
182 24
	protected function s_internal ($string, $single_quotes_around) {
183 24
		$return = $this->instance->real_escape_string($string);
184 24
		return $single_quotes_around ? "'$return'" : $return;
185
	}
186
	/**
187
	 * @inheritdoc
188
	 */
189 1
	public function server () {
190 1
		return $this->instance->server_info;
191
	}
192
	/**
193
	 * @inheritdoc
194
	 */
195 2
	public function __destruct () {
196 2
		if ($this->connected && is_object($this->instance)) {
197 2
			$this->instance->close();
198 2
			$this->connected = false;
199
		}
200 2
	}
201
}
202