1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Foolz\SphinxQL\Drivers\Mysqli; |
4
|
|
|
|
5
|
|
|
use Foolz\SphinxQL\Exception\ConnectionException; |
6
|
|
|
use Foolz\SphinxQL\Exception\DatabaseException; |
7
|
|
|
use Foolz\SphinxQL\Exception\SphinxQLException; |
8
|
|
|
use Foolz\SphinxQL\Drivers\ConnectionBase; |
9
|
|
|
|
10
|
|
|
class Connection extends ConnectionBase |
11
|
|
|
{ |
12
|
|
|
/** |
13
|
|
|
* Internal Encoding |
14
|
|
|
* |
15
|
|
|
* @var string |
16
|
|
|
*/ |
17
|
|
|
protected $internal_encoding = null; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Disables any warning outputs returned on the \MySQLi connection with @ prefix. |
21
|
|
|
* |
22
|
|
|
* @var boolean |
23
|
|
|
*/ |
24
|
|
|
protected $silence_connection_warning = false; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Forces the \MySQLi connection to suppress all errors returned. This should only be used |
28
|
|
|
* when the production server is running with high error reporting settings. |
29
|
|
|
* |
30
|
|
|
* @param boolean $enable True if it should be enabled, false if it should be disabled |
31
|
|
|
*/ |
32
|
|
|
public function silenceConnectionWarning($enable = true) |
33
|
|
|
{ |
34
|
|
|
$this->silence_connection_warning = $enable; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Returns the internal encoding. |
39
|
|
|
* |
40
|
|
|
* @return string current multibyte internal encoding |
41
|
|
|
*/ |
42
|
|
|
public function getInternalEncoding() |
43
|
|
|
{ |
44
|
|
|
return $this->internal_encoding; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Establishes a connection to the Sphinx server with \MySQLi. |
49
|
|
|
* |
50
|
|
|
* @param boolean $suppress_error If the warnings on the connection should be suppressed |
51
|
|
|
* |
52
|
|
|
* @return boolean True if connected |
53
|
|
|
* @throws ConnectionException If a connection error was encountered |
54
|
|
|
*/ |
55
|
|
View Code Duplication |
public function connect($suppress_error = false) |
|
|
|
|
56
|
|
|
{ |
57
|
|
|
$data = $this->getParams(); |
58
|
|
|
$conn = mysqli_init(); |
59
|
|
|
|
60
|
|
|
if (!empty($data['options'])) { |
61
|
|
|
foreach ($data['options'] as $option => $value) { |
62
|
|
|
$conn->options($option, $value); |
63
|
|
|
} |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
if (!$suppress_error && ! $this->silence_connection_warning) { |
67
|
|
|
$conn->real_connect($data['host'], null, null, null, (int) $data['port'], $data['socket']); |
68
|
|
|
} else { |
69
|
|
|
@ $conn->real_connect($data['host'], null, null, null, (int) $data['port'], $data['socket']); |
|
|
|
|
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
if ($conn->connect_error) { |
73
|
|
|
throw new ConnectionException('Connection Error: ['.$conn->connect_errno.']' |
74
|
|
|
.$conn->connect_error); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$conn->set_charset('utf8'); |
78
|
|
|
$this->connection = $conn; |
79
|
|
|
$this->mbPush(); |
80
|
|
|
|
81
|
|
|
return true; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Pings the Sphinx server. |
86
|
|
|
* |
87
|
|
|
* @return boolean True if connected, false otherwise |
88
|
|
|
*/ |
89
|
|
|
public function ping() |
90
|
|
|
{ |
91
|
|
|
$this->ensureConnection(); |
92
|
|
|
return $this->getConnection()->ping(); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Establishes a connection if needed |
97
|
|
|
* @throws ConnectionException |
98
|
|
|
*/ |
99
|
|
|
private function ensureConnection() |
100
|
|
|
{ |
101
|
|
|
try { |
102
|
|
|
$this->getConnection(); |
103
|
|
|
} catch (ConnectionException $e) { |
104
|
|
|
$this->connect(); |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Closes and unset the connection to the Sphinx server. |
110
|
|
|
*/ |
111
|
|
|
public function close() |
112
|
|
|
{ |
113
|
|
|
$this->mbPop(); |
114
|
|
|
$this->getConnection()->close(); |
115
|
|
|
$this->connection = null; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Performs a query on the Sphinx server. |
120
|
|
|
* |
121
|
|
|
* @param string $query The query string |
122
|
|
|
* |
123
|
|
|
* @return ResultSet The result array or number of rows affected |
124
|
|
|
* @throws DatabaseException If the executed query produced an error |
125
|
|
|
*/ |
126
|
|
|
public function query($query) |
127
|
|
|
{ |
128
|
|
|
$this->ensureConnection(); |
129
|
|
|
|
130
|
|
|
$resource = $this->getConnection()->query($query); |
131
|
|
|
|
132
|
|
View Code Duplication |
if ($this->getConnection()->error) { |
|
|
|
|
133
|
|
|
throw new DatabaseException('['.$this->getConnection()->errno.'] '. |
134
|
|
|
$this->getConnection()->error.' [ '.$query.']'); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return new ResultSet($this, $resource); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Performs multiple queries on the Sphinx server. |
142
|
|
|
* |
143
|
|
|
* @param array $queue Queue holding all of the queries to be executed |
144
|
|
|
* |
145
|
|
|
* @return MultiResultSet The result array |
146
|
|
|
* @throws DatabaseException In case a query throws an error |
147
|
|
|
* @throws SphinxQLException In case the array passed is empty |
148
|
|
|
*/ |
149
|
|
|
public function multiQuery(Array $queue) |
150
|
|
|
{ |
151
|
|
|
$count = count($queue); |
152
|
|
|
|
153
|
|
|
if ($count === 0) { |
154
|
|
|
throw new SphinxQLException('The Queue is empty.'); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$this->ensureConnection(); |
158
|
|
|
|
159
|
|
|
// HHVM bug (2015/07/07, HipHop VM 3.8.0-dev (rel)): $mysqli->error and $mysqli->errno aren't set |
160
|
|
View Code Duplication |
if (!$this->getConnection()->multi_query(implode(';', $queue))) { |
|
|
|
|
161
|
|
|
throw new DatabaseException('['.$this->getConnection()->errno.'] '. |
162
|
|
|
$this->getConnection()->error.' [ '.implode(';', $queue).']'); |
163
|
|
|
}; |
164
|
|
|
|
165
|
|
|
return new MultiResultSet($this, $count); |
|
|
|
|
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Escapes the input with \MySQLi::real_escape_string. |
170
|
|
|
* Based on FuelPHP's escaping function. |
171
|
|
|
* |
172
|
|
|
* @param string $value The string to escape |
173
|
|
|
* |
174
|
|
|
* @return string The escaped string |
175
|
|
|
* @throws DatabaseException If an error was encountered during server-side escape |
176
|
|
|
*/ |
177
|
|
View Code Duplication |
public function escape($value) |
|
|
|
|
178
|
|
|
{ |
179
|
|
|
$this->ensureConnection(); |
180
|
|
|
|
181
|
|
|
if (($value = $this->getConnection()->real_escape_string((string) $value)) === false) { |
182
|
|
|
// @codeCoverageIgnoreStart |
183
|
|
|
throw new DatabaseException($this->getConnection()->error, $this->getConnection()->errno); |
184
|
|
|
// @codeCoverageIgnoreEnd |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
return "'".$value."'"; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Enter UTF-8 multi-byte workaround mode. |
192
|
|
|
*/ |
193
|
|
|
public function mbPush() |
194
|
|
|
{ |
195
|
|
|
$this->internal_encoding = mb_internal_encoding(); |
196
|
|
|
mb_internal_encoding('UTF-8'); |
197
|
|
|
|
198
|
|
|
return $this; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Exit UTF-8 multi-byte workaround mode. |
203
|
|
|
*/ |
204
|
|
|
public function mbPop() |
205
|
|
|
{ |
206
|
|
|
mb_internal_encoding($this->internal_encoding); |
207
|
|
|
$this->internal_encoding = null; |
208
|
|
|
|
209
|
|
|
return $this; |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
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.