Completed
Push — master ( 319aa4...523298 )
by smiley
04:24
created

PDODriverAbstract::getServerInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 *
4
 * @filesource   PDODriverAbstract.php
5
 * @created      04.11.2015
6
 * @package      chillerlan\Database\Drivers\PDO
7
 * @author       Smiley <[email protected]>
8
 * @copyright    2015 Smiley
9
 * @license      MIT
10
 */
11
12
namespace chillerlan\Database\Drivers\PDO;
13
14
use chillerlan\Database\DBException;
15
use chillerlan\Database\Drivers\DBDriverAbstract;
16
use chillerlan\Database\Drivers\DBDriverInterface;
17
use PDO;
18
use PDOException;
19
use PDOStatement;
20
21
/**
22
 * Class PDODriverAbstract
23
 *
24
 * @see http://php.net/manual/pdo.constants.php
25
 */
26
abstract class PDODriverAbstract extends DBDriverAbstract{
27
28
	/**
29
	 * Holds the database resource object
30
	 *
31
	 * @var PDO
32
	 */
33
	protected $db;
34
35
	/**
36
	 * Some basic PDO options
37
	 *
38
	 * @see http://php.net/manual/pdo.getattribute.php PDO::getAttribute
39
	 *
40
	 * @var array
41
	 */
42
	protected $pdo_options
43
		= [
44
			PDO::ATTR_CASE              => PDO::CASE_NATURAL,
45
			PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
46
			PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
47
			PDO::ATTR_STRINGIFY_FETCHES => false,
48
			PDO::ATTR_EMULATE_PREPARES  => false,
49
		];
50
51
	/**
52
	 * The PDO drivername which is being used in the DSN
53
	 *
54
	 * @var string
55
	 */
56
	protected $drivername;
57
58
	/**
59
	 * This array holds one or more key=>value pairs to set attribute values for the PDOStatement object that this
60
	 * method returns. You would most commonly use this to set the PDO::ATTR_CURSOR value to PDO::CURSOR_SCROLL to
61
	 * request a scrollable cursor.
62
	 *
63
	 * @var array
64
	 */
65
	protected $pdo_stmt_options = [];
66
67
	/**
68
	 * Returns a DSN string using the given options
69
	 *
70
	 * @link http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html#4.4
71
	 *
72
	 * @return string DSN
73
	 */
74 View Code Duplication
	protected function getDSN():string{
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
		$dsn = $this->drivername;
76
77
		if($this->options->socket){
78
			$dsn .= ':unix_socket='.$this->options->socket;
79
		}
80
		else{
81
			$dsn .= ':host='.$this->options->host;
82
			$dsn .= (bool)$this->options->port ? ';port='.$this->options->port : '';
83
		}
84
85
		$dsn .= ';dbname='.$this->options->database;
86
87
		return $dsn;
88
	}
89
90
	/**
91
	 * Establishes a database connection and returns the connection object
92
	 *
93
	 * @return \chillerlan\Database\Drivers\DBDriverInterface
94
	 * @throws \chillerlan\Database\DBException
95
	 */
96 View Code Duplication
	public function connect():DBDriverInterface{
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
98
		if($this->db instanceof PDO){
99
			return $this;
100
		}
101
102
		if($this->options->use_ssl){
103
			$this->pdo_options += [
104
				PDO::MYSQL_ATTR_SSL_KEY    => $this->options->ssl_key,
105
				PDO::MYSQL_ATTR_SSL_CERT   => $this->options->ssl_cert,
106
				PDO::MYSQL_ATTR_SSL_CA     => $this->options->ssl_ca,
107
				PDO::MYSQL_ATTR_SSL_CAPATH => $this->options->ssl_capath,
108
				PDO::MYSQL_ATTR_SSL_CIPHER => $this->options->ssl_cipher,
109
			];
110
		}
111
112
		try{
113
			$this->db = new PDO($this->getDSN(), $this->options->username, $this->options->password, $this->pdo_options);
114
		}
115
		catch(PDOException $PDOException){
116
			throw new DBException($PDOException->getMessage());
117
		}
118
119
		return $this;
120
	}
121
122
	/**
123
	 * Closes a database connection
124
	 *
125
	 * @return bool
126
	 */
127
	public function disconnect():bool{
128
		$this->db = null;
129
130
		return true;
131
	}
132
133
	/**
134
	 * Returns info about the used php client
135
	 *
136
	 * @return string php's database client string
137
	 */
138
	public function getClientInfo():string{
139
		return $this->db->getAttribute(PDO::ATTR_CLIENT_VERSION);
140
	}
141
142
	/**
143
	 * Returns info about the database server
144
	 *
145
	 * @return string database's serverinfo string
146
	 */
147
	public function getServerInfo():string{
148
		return $this->db->getAttribute(PDO::ATTR_SERVER_INFO);
149
	}
150
151
	/**
152
	 * @param $data
153
	 *
154
	 * @return string
155
	 */
156
	protected function __escape($data){
157
		return $this->db->quote($data);
158
	}
159
160
	/**
161
	 * @param \PDOStatement $stmt
162
	 * @param array         $values
163
	 *
164
	 * @return void
165
	 */
166 View Code Duplication
	protected function bindParams(PDOStatement &$stmt, array $values){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
167
		$param_no = 1;
168
169
		foreach($values as $v){
170
171
			switch(gettype($v)){
172
				case 'boolean':
173
					$type = PDO::PARAM_BOOL;
174
					break;
175
				case 'integer':
176
					$type = PDO::PARAM_INT;
177
					break;
178
				case 'NULL':
179
					$type = PDO::PARAM_NULL;
180
					break;
181
				default:
182
					$type = PDO::PARAM_STR;
183
					break;
184
			}
185
186
			$stmt->bindValue($param_no, $v, $type);
187
			$param_no++;
188
		}
189
	}
190
191
	/**
192
	 * Returns the last insert id (if present)
193
	 *
194
	 * @link http://php.net/manual/pdo.lastinsertid.php
195
	 * @return string
196
	 */
197
	protected function insertID():string{
198
		return $this->db->lastInsertId();
199
	}
200
201
	/**
202
	 * @param             $stmt
203
	 * @param string|null $index
204
	 * @param bool        $assoc
205
	 *
206
	 * @return bool|\chillerlan\Database\DBResult
207
	 */
208
	protected function __getResult($stmt, string $index = null, bool $assoc = true){
209
210
		if(is_bool($stmt)){
211
			return $stmt;
212
		}
213
214
		return $this->getResult([$stmt, 'fetch'], [$assoc ? PDO::FETCH_ASSOC : PDO::FETCH_NUM], $index, $assoc);
215
	}
216
217
	/**
218
	 * @param string      $sql
219
	 * @param string|null $index
220
	 * @param bool        $assoc
221
	 *
222
	 * @return bool|\chillerlan\Database\DBResult
223
	 */
224
	protected function __raw(string $sql, string $index = null, bool $assoc = true){
225
		return $this->__getResult($this->db->query($sql), $index, $assoc);
226
	}
227
228
	/**
229
	 * @param string      $sql
230
	 * @param array       $values
231
	 * @param string|null $index
232
	 * @param bool        $assoc
233
	 *
234
	 * @return bool|\chillerlan\Database\DBResult
235
	 */
236
	protected function __prepared(string $sql, array $values = [], string $index = null, bool $assoc = true){
237
		$stmt = $this->db->prepare($sql, $this->pdo_stmt_options);
238
239
		if(!empty($values)){
240
			$this->bindParams($stmt, $values);
241
		}
242
243
		$stmt->execute();
244
245
		return $this->__getResult($stmt, $index, $assoc);
246
	}
247
248
	/**
249
	 * @param string $sql
250
	 * @param array  $values
251
	 *
252
	 * @return bool
253
	 */
254 View Code Duplication
	protected function __multi(string $sql, array $values){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
		$stmt = $this->db->prepare($sql, $this->pdo_stmt_options);
256
257
		foreach($values as $row){
258
			$this->bindParams($stmt, $row);
259
			$stmt->execute();
260
		}
261
262
		$stmt = null;
0 ignored issues
show
Unused Code introduced by
$stmt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
263
264
		return true;
265
	}
266
267
	/**
268
	 * @param string $sql
269
	 * @param array  $data
270
	 * @param        $callback
271
	 *
272
	 * @return bool
273
	 */
274 View Code Duplication
	protected function __multi_callback(string $sql, array $data, $callback){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
		$stmt = $this->db->prepare($sql, $this->pdo_stmt_options);
276
277
		foreach($data as $row){
278
			$this->bindParams($stmt, call_user_func_array($callback, [$row]));
279
			$stmt->execute();
280
		}
281
282
		$stmt = null;
0 ignored issues
show
Unused Code introduced by
$stmt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
283
284
		return true;
285
	}
286
}
287