1: | <?php
2: | namespace Opencart\System\Library\DB;
3: | /**
4: | * Class MySQLi
5: | *
6: | * @package Opencart\System\Library\DB
7: | */
8: | class MySQLi {
9: | /**
10: | * @var ?\mysqli
11: | */
12: | private ?\mysqli $connection;
13: |
14: | /**
15: | * Constructor
16: | *
17: | * @param string $hostname
18: | * @param string $username
19: | * @param string $password
20: | * @param string $database
21: | * @param int $port
22: | * @param string $ssl_key
23: | * @param string $ssl_cert
24: | * @param string $ssl_ca
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: | // MSQL SSL connection
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: | // Sync PHP and DB time zones
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: | * Query
92: | *
93: | * @param string $sql
94: | *
95: | * @return mixed
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: | * Escape
128: | *
129: | * @param string $value
130: | *
131: | * @return string
132: | */
133: | public function escape(string $value): string {
134: | return $this->connection->real_escape_string($value);
135: | }
136: |
137: | /**
138: | * countAffected
139: | *
140: | * @return int
141: | */
142: | public function countAffected(): int {
143: | return $this->connection->affected_rows;
144: | }
145: |
146: | /**
147: | * getLastId
148: | *
149: | * @return int
150: | */
151: | public function getLastId(): int {
152: | return $this->connection->insert_id;
153: | }
154: |
155: | /**
156: | * isConnected
157: | *
158: | * @return bool
159: | */
160: | public function isConnected(): bool {
161: | return $this->connection !== null;
162: | }
163: |
164: | /**
165: | * Destructor
166: | *
167: | * Closes the DB connection when this object is destroyed.
168: | */
169: | public function __destruct() {
170: | if ($this->connection) {
171: | $this->connection->close();
172: |
173: | $this->connection = null;
174: | }
175: | }
176: | }
177: |

OpenCart API API documentation generated by ApiGen dev-master