1: | <?php
|
2: | namespace Opencart\System\Library\DB;
|
3: | |
4: | |
5: | |
6: | |
7: |
|
8: | class MySQLi {
|
9: | |
10: | |
11: |
|
12: | private ?\mysqli $connection;
|
13: |
|
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | |
25: |
|
26: | public function __construct(string $hostname, string $username, string $password, string $database, int $port = 0, string $ssl_key = '', string $ssl_cert = '', string $ssl_ca = '') {
|
27: | if (!$port) {
|
28: | $port = 3306;
|
29: | }
|
30: |
|
31: |
|
32: | $temp_ssl_key_file = '';
|
33: |
|
34: | if ($ssl_key) {
|
35: | $temp_ssl_key_file = tempnam(sys_get_temp_dir(), 'mysqli_key_');
|
36: |
|
37: | $handle = fopen($temp_ssl_key_file, 'w');
|
38: |
|
39: | fwrite($handle, $ssl_key);
|
40: |
|
41: | fclose($handle);
|
42: | }
|
43: |
|
44: | $temp_ssl_cert_file = '';
|
45: |
|
46: | if ($ssl_cert) {
|
47: | $temp_ssl_cert_file = tempnam(sys_get_temp_dir(), 'mysqli_cert_');
|
48: |
|
49: | $handle = fopen($temp_ssl_cert_file, 'w');
|
50: |
|
51: | fwrite($handle, $ssl_cert);
|
52: |
|
53: | fclose($handle);
|
54: | }
|
55: |
|
56: | $temp_ssl_ca_file = '';
|
57: |
|
58: | if ($ssl_ca) {
|
59: | $temp_ssl_ca_file = tempnam(sys_get_temp_dir(), 'mysqli_ca_');
|
60: |
|
61: | $handle = fopen($temp_ssl_ca_file, 'w');
|
62: |
|
63: | fwrite($handle, '-----BEGIN CERTIFICATE-----' . PHP_EOL . $ssl_ca . PHP_EOL . '-----END CERTIFICATE-----');
|
64: |
|
65: | fclose($handle);
|
66: | }
|
67: |
|
68: | try {
|
69: | $this->connection = mysqli_init() ?: null;
|
70: |
|
71: | if ($temp_ssl_key_file || $temp_ssl_cert_file || $temp_ssl_ca_file) {
|
72: | $this->connection->ssl_set($temp_ssl_key_file, $temp_ssl_cert_file, $temp_ssl_ca_file, null, null);
|
73: | $this->connection->real_connect($hostname, $username, $password, $database, $port, null, MYSQLI_CLIENT_SSL);
|
74: | } else {
|
75: | $this->connection->real_connect($hostname, $username, $password, $database, $port, null);
|
76: | }
|
77: |
|
78: | $this->connection->set_charset('utf8mb4');
|
79: |
|
80: | $this->query("SET SESSION sql_mode = 'NO_ZERO_IN_DATE,NO_ENGINE_SUBSTITUTION'");
|
81: | $this->query("SET FOREIGN_KEY_CHECKS = 0");
|
82: |
|
83: |
|
84: | $this->query("SET `time_zone` = '" . $this->escape(date('P')) . "'");
|
85: | } catch (\mysqli_sql_exception $e) {
|
86: | throw new \Exception('Error: Could not make a database link using ' . $username . '@' . $hostname . '!<br/>Message: ' . $e->getMessage());
|
87: | }
|
88: | }
|
89: |
|
90: | |
91: | |
92: | |
93: | |
94: | |
95: | |
96: |
|
97: | public function query(string $sql) {
|
98: | try {
|
99: | $query = $this->connection->query($sql);
|
100: |
|
101: | if ($query instanceof \mysqli_result) {
|
102: | $data = [];
|
103: |
|
104: | while ($row = $query->fetch_assoc()) {
|
105: | $data[] = $row;
|
106: | }
|
107: |
|
108: | $result = new \stdClass();
|
109: | $result->num_rows = $query->num_rows;
|
110: | $result->row = $data[0] ?? [];
|
111: | $result->rows = $data;
|
112: |
|
113: | $query->close();
|
114: |
|
115: | unset($data);
|
116: |
|
117: | return $result;
|
118: | } else {
|
119: | return true;
|
120: | }
|
121: | } catch (\mysqli_sql_exception $e) {
|
122: | throw new \Exception('Error: ' . $this->connection->error . '<br/>Error No: ' . $this->connection->errno . '<br/>' . $sql);
|
123: | }
|
124: | }
|
125: |
|
126: | |
127: | |
128: | |
129: | |
130: | |
131: | |
132: |
|
133: | public function escape(string $value): string {
|
134: | return $this->connection->real_escape_string($value);
|
135: | }
|
136: |
|
137: | |
138: | |
139: | |
140: | |
141: |
|
142: | public function countAffected(): int {
|
143: | return $this->connection->affected_rows;
|
144: | }
|
145: |
|
146: | |
147: | |
148: | |
149: | |
150: |
|
151: | public function getLastId(): int {
|
152: | return $this->connection->insert_id;
|
153: | }
|
154: |
|
155: | |
156: | |
157: | |
158: | |
159: |
|
160: | public function isConnected(): bool {
|
161: | return $this->connection !== null;
|
162: | }
|
163: |
|
164: | |
165: | |
166: | |
167: | |
168: |
|
169: | public function __destruct() {
|
170: | if ($this->connection) {
|
171: | $this->connection->close();
|
172: |
|
173: | $this->connection = null;
|
174: | }
|
175: | }
|
176: | }
|
177: | |