Warning: mysqli::__construct(): php_network_getaddresses: getaddrinfo for mysql failed: Try again in /var/www/html/system/db/mysqli.php on line 295 Exception:
Array
(
[message] => php_network_getaddresses: getaddrinfo for mysql failed: Try again
[file] => /var/www/html/system/db/mysqli.php
[line_no] => 299
[line] => throw new \Exception($errorMessage, $e->getCode()); // <==
[lines] => Array
(
[0] =>
[1] => try {
[2] => self :: $link = new \Mysqli(/*'p:' . */$host, $user, $pass, $dbname, $port);
[3] => //self :: $link = $this;
[4] => } catch (\mysqli_sql_exception $e) {
[5] => $errorMessage = str_replace($pass,'*****', $e->getMessage());
[6] =>
[7] => throw new \Exception($errorMessage, $e->getCode()); // <==
[8] => }
[9] =>
[10] => // check if a connection established
[11] => if (\mysqli_connect_errno()) {
[12] => $error = mysqli_connect_error();
[13] => $errorMessage = str_replace($pass,'*****', $error);
)
[trace] => #0 /var/www/html/system/db/mysqli.php(615): Vvveb\System\Db\Mysqli->connect()
#1 /var/www/html/storage/model/app/productsql.mysqli.php(6895): Vvveb\System\Db\Mysqli->execute('SELECT pd.*,pr...', Array, Array)
#2 /var/www/html/app/component/products.php(179): Vvveb\Sql\ProductSQL->getAll(Array)
#3 /var/www/html/system/component/component.php(206): Vvveb\Component\Products->results()
#4 /var/www/html/system/component/component.php(134): Vvveb\System\Component\Component->loadComponents()
#5 /var/www/html/system/component/component.php(91): Vvveb\System\Component\Component->__construct(Object(Vvveb\System\Core\View), false, NULL, NULL)
#6 /var/www/html/system/core/view.php(523): Vvveb\System\Component\Component::getInstance(Object(Vvveb\System\Core\View), false, NULL)
#7 /var/www/html/system/core/response.php(161): Vvveb\System\Core\View->render(true, true)
#8 /var/www/html/system/core/frontcontroller.php(287): Vvveb\System\Core\Response->output()
#9 /var/www/html/system/core/frontcontroller.php(337): Vvveb\System\Core\FrontController::call('Vvveb\\Controlle...', 'index', '/var/www/html/a...')
#10 /var/www/html/system/core/frontcontroller.php(426): Vvveb\System\Core\FrontController::redirect('Index', 'index')
#11 /var/www/html/system/core/startup.php(514): Vvveb\System\Core\FrontController::dispatch(Array)
#12 /var/www/html/index.php(170): Vvveb\System\Core\start()
#13 /var/www/html/public/index.php(28): include('/var/www/html/i...')
#14 {main}
[code] => Array
(
[0] =>
[2] => /**
[3] => * Vvveb
[4] => *
[5] => * Copyright (C) 2022 Ziadin Givan
[6] => *
[7] => * This program is free software: you can redistribute it and/or modify
[8] => * it under the terms of the GNU Affero General Public License as
[9] => * published by the Free Software Foundation, either version 3 of the
[10] => * License, or (at your option) any later version.
[11] => *
[12] => * This program is distributed in the hope that it will be useful,
[13] => * but WITHOUT ANY WARRANTY; without even the implied warranty of
[14] => * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[15] => * GNU Affero General Public License for more details.
[16] => *
[17] => * You should have received a copy of the GNU Affero General Public License
[18] => * along with this program. If not, see .
[19] => *
[20] => */
[21] =>
[22] => namespace Vvveb\System\Db;
[23] =>
[24] => use Vvveb\System\Event;
[25] =>
[26] => /**
[27] => * Polyfill for mysqli_result when native fetch_all is missing on mysqli_stmt.
[28] => *
[29] => * Wraps a prepared statement and provides fetch_all, fetch_assoc, and fetchRow
[30] => * methods by binding result columns and iterating through the statement.
[31] => */
[32] => class mysqli_result {
[33] => /** @var \mysqli_stmt The underlying prepared statement. */
[34] => private \mysqli_stmt $stmt;
[35] =>
[36] => /** @var ?\mysqli_result Metadata for the statement result. */
[37] => private ?\mysqli_result $meta = null;
[38] =>
[39] => /** @var array row. */
[40] => private $row = [];
[41] =>
[42] => /**
[43] => * @param \mysqli_stmt $stmt The prepared statement to wrap.
[44] => */
[45] => public function __construct(\mysqli_stmt $stmt) {
[46] => $this->stmt = $stmt;
[47] =>
[48] => $this->stmt->store_result();
[49] => $meta = $this->stmt->result_metadata();
[50] => if ($meta) {
[51] => $this->row = [];
[52] => /*
[53] => for ($i = 0;$i < $meta->field_count; $i++) {
[54] => $field = $meta->fetch_field_direct($i);
[55] => $name = $field->name;
[56] => $this->row[$name] = [];
[57] => $params[] = &$this->row[$name];
[58] => }
[59] => */
[60] =>
[61] => while ($field = $meta->fetch_field()) {
[62] => $name = $result = preg_replace('/[^a-zA-Z0-9_-]+/', '', $field->name);
[63] => $this->row[$name] = [];
[64] => $params[] = &$this->row[$name];
[65] => }
[66] =>
[67] => call_user_func_array([$this->stmt, 'bind_result'], $params);
[68] => }
[69] => }
[70] =>
[71] => /**
[72] => * Fetch all rows as an associative array (delegates to fetch_assoc).
[73] => *
[74] => * @return array> All result rows.
[75] => */
[76] => public function fetch_all(): array {
[77] => return $this->fetch_assoc();
[78] => }
[79] =>
[80] => /**
[81] => * Fetch all rows as an associative array (delegates to fetch_assoc).
[82] => *
[83] => * @param int $resulttype Ignored — always returns associative.
[84] => *
[85] => * @return array>|null All result rows.
[86] => */
[87] => public function fetch_array(int $resulttype): ?array {
[88] => if ($result = $this->stmt->fetch()) {
[89] => //dereference
[90] => foreach ($this->row as $key => $value) {
[91] => if ($resulttype == MYSQLI_ASSOC) {
[92] => $row[$key] = $value;
[93] => } else {
[94] => $row[] = $value;
[95] => }
[96] => }
[97] =>
[98] => return $row;
[99] => } else {
[100] => //$this->stmt->close();
[101] => return $result;
[102] => }
[103] => }
[104] =>
[105] => /**
[106] => * Fetch all rows as an associative array by binding result columns.
[107] => *
[108] => * @return array> All result rows.
[109] => */
[110] => public function fetch_assoc(): array {
[111] => $result = [];
[112] => while ($return = $this->stmt->fetch()) {
[113] => $c = [];
[114] =>
[115] => $row = $this->row;
[116] => foreach ($row as $key => $val) {
[117] => $c[$key] = $val;
[118] => }
[119] => $result[] = $c;
[120] => }
[121] =>
[122] => return $result;
[123] => }
[124] =>
[125] => /**
[126] => * Stub for interface compatibility — does nothing.
[127] => *
[128] => * @return void
[129] => */
[130] => public function fetch_field(): void {
[131] => }
[132] =>
[133] => /**
[134] => * Stub for interface compatibility — does nothing.
[135] => *
[136] => * @return void
[137] => */
[138] => public function fetch_fields(): void {
[139] => }
[140] =>
[141] => /**
[142] => * Fetch all rows as an associative array (alias for fetch_assoc).
[143] => *
[144] => * @return array> All result rows.
[145] => */
[146] => public function fetchRow(): array {
[147] => if ($result = $this->stmt->fetch()) {
[148] => //dereference
[149] => foreach ($this->row as $key => $value) {
[150] => $row[$key] = $value;
[151] => }
[152] => return $row;
[153] => } else {
[154] => //$this->stmt->close();
[155] => return $result;
[156] => }
[157] => }
[158] =>
[159] => private function destroy() {
[160] => $this->stmt->close();
[161] => }
[162] => }
[163] =>
[164] => /**
[165] => * MySQL database driver using the mysqli extension.
[166] => *
[167] => * Provides connection management, query execution with prepared statements,
[168] => * result fetching, escaping, and schema introspection for MySQL/MariaDB.
[169] => */
[170] => class Mysqli extends DBDriver {
[171] => /** @var ?\MySQLi The shared database connection (singleton per process). */
[172] => private static ?\MySQLi $link = null;
[173] =>
[174] => /** @var ?\mysqli_stmt The current prepared statement, if any. */
[175] => private ?\mysqli_stmt $stmt = null;
[176] =>
[177] => /** @var int Number of rows affected by the last query. */
[178] => public int $affected_rows = 0;
[179] =>
[180] => /** @var ?int The auto-increment ID generated by the last INSERT. */
[181] => public ?int $insert_id = null;
[182] =>
[183] => /** @var string Identifier quote character for MySQL. */
[184] => public string $quote = '`';
[185] =>
[186] => /** @var string Table name prefix. */
[187] => public string $prefix = ''; //'vv_';
[188] =>
[189] => /**
[190] => * Get the MySQL server version as an integer.
[191] => *
[192] => * @return int|null The server version (e.g. 80031) or null if not connected.
[193] => */
[194] => public static function version(): ?int {
[195] => if (self :: $link) {
[196] => return mysqli_get_server_version(self :: $link);
[197] => }
[198] =>
[199] => return null;
[200] => }
[201] =>
[202] => /**
[203] => * Get the MySQL server version string.
[204] => *
[205] => * @return string|null The version string (e.g. '8.0.31') or null if not connected.
[206] => */
[207] => public static function info(): ?string {
[208] => if (self :: $link) {
[209] => return mysqli_get_server_info(self :: $link);
[210] => }
[211] =>
[212] => return null;
[213] => }
[214] =>
[215] => /**
[216] => * Get the error message from the last MySQL operation.
[217] => *
[218] => * @return string|null The error message, or null if not connected.
[219] => */
[220] => public function error(): ?string {
[221] => if (self :: $link) {
[222] => return self :: $link->error;
[223] => }
[224] =>
[225] => return null;
[226] => }
[227] =>
[228] => /**
[229] => * Get the error code from the last MySQL operation.
[230] => *
[231] => * @return int|null The error code, or null if not connected.
[232] => */
[233] => public function errorCode(): ?int {
[234] => if (self :: $link) {
[235] => return self :: $link->errno;
[236] => }
[237] =>
[238] => return null;
[239] => }
[240] =>
[241] => /**
[242] => * Wrap a mysqli_stmt in a mysqli_result polyfill for fetch_all support.
[243] => *
[244] => * @param \mysqli_stmt $stmt The prepared statement.
[245] => *
[246] => * @return mysqli_result The polyfilled result object.
[247] => */
[248] => public function get_result(\mysqli_stmt $stmt): mysqli_result {
[249] => $result = new mysqli_result($stmt);
[250] =>
[251] => return $result;
[252] => }
[253] =>
[254] => /**
[255] => * @param string $host Database host.
[256] => * @param string $dbname Database name.
[257] => * @param string $user Database user.
[258] => * @param string $pass Database password.
[259] => * @param int|null $port Database port.
[260] => * @param string $prefix Table name prefix.
[261] => */
[262] => public function __construct(string $host = DB_HOST, string $dbname = DB_NAME, string $user = DB_USER, string $pass = DB_PASS, int|null $port = DB_PORT, string $prefix = DB_PREFIX) {
[263] => //return $this->connect($host, $dbname, $user, $pass, $port, $prefix);
[264] => }
[265] =>
[266] => /**
[267] => * Connect to the MySQL database.
[268] => *
[269] => * Uses a singleton pattern — returns the existing connection if already open.
[270] => * Throws an exception with a sanitised error message on failure.
[271] => *
[272] => * @param string $host Database host.
[273] => * @param string $dbname Database name.
[274] => * @param string $user Database user.
[275] => * @param string $pass Database password.
[276] => * @param int|null $port Database port.
[277] => * @param string $prefix Table name prefix.
[278] => *
[279] => * @return ?\MySQLi The database connection, or null on failure.
[280] => *
[281] => * @throws \Exception On connection failure.
[282] => */
[283] => public function connect(string $host = DB_HOST, string $dbname = DB_NAME, string $user = DB_USER, string $pass = DB_PASS, int|null $port = DB_PORT, string $prefix = DB_PREFIX): ?\MySQLi {
[284] => //mysqli_report(MYSQLI_REPORT_OFF);
[285] => //connect to database
[286] => if (self :: $link) {
[287] => return self :: $link;
[288] => }
[289] => $this->prefix = $prefix;
[290] =>
[291] => \mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
[292] =>
[293] => try {
[294] => self :: $link = new \Mysqli(/*'p:' . */$host, $user, $pass, $dbname, $port);
[295] => //self :: $link = $this;
[296] => } catch (\mysqli_sql_exception $e) {
[297] => $errorMessage = str_replace($pass,'*****', $e->getMessage());
[298] =>
[299] => throw new \Exception($errorMessage, $e->getCode()); // <==
[300] => }
[301] =>
[302] => // check if a connection established
[303] => if (\mysqli_connect_errno()) {
[304] => $error = mysqli_connect_error();
[305] => $errorMessage = str_replace($pass,'*****', $error);
[306] =>
[307] => throw new \Exception($errorMessage, mysqli_connect_errno());
[308] => }
[309] =>
[310] => if ((! self :: $link instanceof \MySQLi)) {
[311] => throw new \Exception('Mysqli not an object', mysqli_connect_errno());
[312] => }
[313] =>
[314] => //sync database time
[315] => //$this->execute('SET `time_zone` = :zone', ['zone' => $this->escape(date('P'))]);
[316] =>
[317] => return self :: $link;
[318] => }
[319] =>
[320] => /**
[321] => * Get all columns for a table used for sanitizing input.
[322] => *
[323] => * @param string $tableName The table name to introspect.
[324] => * @param bool $comment Whether to include the column comment field.
[325] => *
[326] => * @return array|false
[327] => * Associative array keyed by column name, or false on failure.
[328] => */
[329] => public function getColumnsMeta(string $tableName, bool $comment = false): array|false {
[330] => $sql =
[331] => 'SELECT COLUMN_NAME as name, COLUMN_DEFAULT as d, IS_NULLABLE as n, DATA_TYPE as t, EXTRA as e, CHARACTER_MAXIMUM_LENGTH as l'
[332] => . ($comment ? ', COLUMN_COMMENT as c' : '') .
[333] => ' FROM `INFORMATION_SCHEMA`.`COLUMNS`
[334] => WHERE `TABLE_SCHEMA`= "' . DB_NAME . '"
[335] => AND `TABLE_NAME`="' . $tableName . '"';
[336] =>
[337] => if ($result = $this->query($sql)) {
[338] => //$columns = $result->fetch_all(MYSQLI_ASSOC);
[339] => $columns = [];
[340] =>
[341] => while ($row = $result->fetch_assoc()) {
[342] => $columns[$row['name']] = $row;
[343] => }
[344] =>
[345] => /* free result set */
[346] => $result->close();
[347] =>
[348] => return $columns;
[349] => } else {
[350] => }
[351] =>
[352] => return false;
[353] => }
[354] =>
[355] => /**
[356] => * Get all table names in the database.
[357] => *
[358] => * @param string $db The database name.
[359] => *
[360] => * @return array|false List of table names, or false on failure.
[361] => */
[362] => public function getTableNames(string $db = DB_NAME): array|false {
[363] => $sql ="SELECT table_name as name
[364] => FROM information_schema.tables
[365] => WHERE table_schema = '$db' ORDER BY table_name";
[366] =>
[367] => if ($result = $this->query($sql)) {
[368] => //$names = $result->fetch_all(MYSQLI_ASSOC);
[369] => $names = [];
[370] =>
[371] => while ($row = $result->fetch_assoc()) {
[372] => $names[] = $row['name'];
[373] => }
[374] =>
[375] => /* free result set */
[376] => $result->close();
[377] =>
[378] => return $names;
[379] => } else {
[380] => }
[381] =>
[382] => return false;
[383] => }
[384] =>
[385] => /**
[386] => * Select a different database on the current connection.
[387] => *
[388] => * @param string $db The database name.
[389] => *
[390] => * @return bool True on success, false on failure.
[391] => */
[392] => public function select_db(string $db): bool {
[393] => return self :: $link->select_db($db);
[394] => }
[395] =>
[396] => /**
[397] => * Execute a raw SQL query.
[398] => *
[399] => * Automatically connects if not connected. Updates affected_rows and insert_id.
[400] => *
[401] => * @param string $sql The SQL query to execute.
[402] => *
[403] => * @return bool|\mysqli_result Query result or true for success, false on failure.
[404] => *
[405] => * @throws \Exception On query failure.
[406] => */
[407] => public function query(string $sql): bool|\mysqli_result {
[408] => if (! self :: $link) {
[409] => $this->connect();
[410] => }
[411] =>
[412] => if (LOG_SQL_QUERIES) {
[413] => error_log($sql);
[414] => }
[415] =>
[416] => try {
[417] => $result = self :: $link->query($sql);
[418] => } catch (\mysqli_sql_exception $e) {
[419] => $message = $e->getMessage() . "\n" . $sql . "\n - " . print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1), true);
[420] =>
[421] => throw new \Exception($message, $e->getCode());
[422] => }
[423] =>
[424] => if ($result) {
[425] => $this->affected_rows = self :: $link->affected_rows;
[426] => $this->insert_id = self :: $link->insert_id;
[427] => }
[428] =>
[429] => return $result;
[430] => }
[431] =>
[432] => /**
[433] => * Execute multiple SQL statements in a single call.
[434] => *
[435] => * @param string $sql The SQL statements to execute (semicolon-separated).
[436] => *
[437] => * @return bool True on success, false on failure.
[438] => */
[439] => public function multi_query(string $sql): bool {
[440] => if (! self :: $link) {
[441] => $this->connect();
[442] => }
[443] =>
[444] => $result = self :: $link->multi_query($sql);
[445] =>
[446] => if ($result) {
[447] => $this->affected_rows = self :: $link->affected_rows;
[448] => $this->insert_id = self :: $link->insert_id;
[449] => }
[450] =>
[451] => return $result;
[452] => }
[453] =>
[454] => /**
[455] => * Escape a value for safe inclusion in a SQL query.
[456] => *
[457] => * Strings are escaped with real_escape_string. Null values become 'null'.
[458] => * All other types are returned as-is.
[459] => *
[460] => * @param mixed $string The value to escape.
[461] => *
[462] => * @return mixed The escaped value.
[463] => */
[464] => public function escape(mixed $string): mixed {
[465] => if (is_string($string)) {
[466] => return self :: $link->real_escape_string($string);
[467] => }
[468] =>
[469] => if (is_null($string)) {
[470] => return 'null';
[471] => }
[472] =>
[473] => return $string;
[474] => }
[475] =>
[476] => /**
[477] => * Escape a string value for use in a SQL literal.
[478] => *
[479] => * @param string $string The string to escape.
[480] => *
[481] => * @return string The escaped string.
[482] => */
[483] => public function escapeLiteral(string $string): string {
[484] => return $this->escape($string);
[485] => }
[486] =>
[487] => /**
[488] => * Generate a MySQL-compatible LIMIT clause.
[489] => *
[490] => * @param int|string $start Offset (0-based).
[491] => * @param int|string $limit Maximum number of rows.
[492] => *
[493] => * @return string The LIMIT clause (e.g. 'LIMIT 0, 10').
[494] => */
[495] => public function sqlLimit(int|string $start, int|string $limit): string {
[496] => return "LIMIT $start, $limit";
[497] => }
[498] =>
[499] => /**
[500] => * Fetch a single row from a statement or result set.
[501] => *
[502] => * @param \mysqli_stmt|\mysqli_result $stmt The statement or result to fetch from.
[503] => *
[504] => * @return array The fetched row, or empty array if no rows.
[505] => */
[506] => public function fetchArray(\mysqli_stmt|\mysqli_result $stmt): array {
[507] => $data = [];
[508] => $statement = (get_class($stmt) === 'mysqli_stmt');
[509] =>
[510] => if ($statement) {
[511] => $this->store_result();
[512] => $result = $stmt->get_result();
[513] => } else {
[514] => $result = $stmt;
[515] => }
[516] =>
[517] => if ($result) {
[518] => $data = $result->fetch_array(MYSQLI_ASSOC);
[519] =>
[520] => if ($statement && $stmt->more_results()) {
[521] => $stmt->next_result();
[522] => }
[523] => }
[524] =>
[525] => return $data;
[526] => }
[527] =>
[528] => /**
[529] => * Fetch all rows from a statement or result set.
[530] => *
[531] => * @param \mysqli_stmt|\mysqli_result $stmt The statement or result to fetch from.
[532] => *
[533] => * @return array> All result rows.
[534] => */
[535] => public function fetchAll(\mysqli_stmt|\mysqli_result $stmt): array {
[536] => $data = [];
[537] => $statement = (get_class($stmt) === 'mysqli_stmt');
[538] =>
[539] => if ($statement) {
[540] => $this->store_result();
[541] => $result = $stmt->get_result();
[542] => } else {
[543] => $result = $stmt;
[544] => }
[545] =>
[546] => if ($result) {
[547] => $data = $result->fetch_all(MYSQLI_ASSOC);
[548] => }
[549] =>
[550] => return $data;
[551] => }
[552] =>
[553] => /**
[554] => * Store the result of the last query in the client-side buffer.
[555] => *
[556] => * @return ?\mysqli_result The stored result, or null on failure.
[557] => */
[558] => public function store_result(): \mysqli_result|false {
[559] => return self :: $link->store_result();
[560] => }
[561] =>
[562] => /**
[563] => * Check if the current statement has more result sets.
[564] => *
[565] => * @return bool True if more results are available.
[566] => */
[567] => public function more_results(): bool {
[568] => return self :: $link->more_results();
[569] => }
[570] =>
[571] => /**
[572] => * Move to the next result set in a multi-query.
[573] => *
[574] => * @return bool True on success, false on failure.
[575] => */
[576] => public function next_result(): bool {
[577] => return self :: $link->next_result();
[578] => }
[579] =>
[580] => /**
[581] => * Close the database connection.
[582] => *
[583] => * @return ?bool True on success, null if not connected.
[584] => */
[585] => public function close(): ?bool {
[586] => if ((self :: $link instanceof \MySQLi)/* && self :: $link->ping()*/) {
[587] => return self :: $link->close();
[588] => }
[589] =>
[590] => return null;
[591] => }
[592] =>
[593] => /**
[594] => * Prepare and execute a parameterized query.
[595] => *
[596] => * Fires an Event::trigger hook before execution. Converts named parameters
[597] => * to positional placeholders, binds parameters, and executes the statement.
[598] => * Updates affected_rows and insert_id on success.
[599] => *
[600] => * @param string $sql The SQL query with :named parameters.
[601] => * @param array $params Named parameter values.
[602] => * @param array $paramTypes Optional explicit type overrides.
[603] => *
[604] => * @return ?\mysqli_stmt The executed statement, or null on failure.
[605] => *
[606] => * @throws \Exception On prepare or execute failure.
[607] => */
[608] => public function execute(string $sql, array $params = [], array $paramTypes = []): ?\mysqli_stmt {
[609] => list($sql, $params) = Event::trigger(__CLASS__,__FUNCTION__, $sql, $params);
[610] => //save orig sql for debugging info
[611] => $origSql = $sql;
[612] =>
[613] => if (! self :: $link) {
[614] => $this->connect();
[615] => }
[616] =>
[617] => list($parameters, $types) = $this->paramsToQmark($sql, $params, $paramTypes);
[618] =>
[619] => try {
[620] => $stmt = self::$link->prepare($sql);
[621] => } catch (\mysqli_sql_exception $e) {
[622] => $message = $e->getMessage() . "\n" . $this->debugSql($origSql, $params, $paramTypes) . "\n - " . $origSql . "\n - " . print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1), true);
[623] =>
[624] => throw new \Exception($message, $e->getCode());
[625] => }
[626] =>
[627] => if ($stmt && ! empty($types)) {
[628] => array_unshift($parameters, $types);
[629] =>
[630] => //hack for php 7.x bind_param "expected to be a reference, value given" stupid warning
[631] => $referenceArray = [];
[632] =>
[633] => foreach ($parameters as $key => $value) {
[634] => $referenceArray[$key] = &$parameters[$key];
[635] => }
[636] =>
[637] => @call_user_func_array([$stmt, 'bind_param'], $referenceArray);
[638] => }
[639] =>
[640] => if (LOG_SQL_QUERIES) {
[641] => error_log($this->debugSql($origSql, $params, $paramTypes));
[642] => }
[643] =>
[644] => if ($stmt) {
[645] => try {
[646] => if ($stmt->execute()) {
[647] => $this->affected_rows = self :: $link->affected_rows;
[648] => $this->insert_id = self :: $link->insert_id;
[649] =>
[650] => return $stmt;
[651] => } else {
[652] => error_log(print_r($stmt, 1));
[653] => error_log($this->debugSql($sql, $params, $paramTypes));
[654] => }
[655] => } catch (\mysqli_sql_exception $e) {
[656] => $message = $e->getMessage() . "\n" . $origSql . "\n" . $this->debugSql($origSql, $params, $paramTypes) . "\n" . print_r($parameters, 1) . $types . "\n" . print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1), true);
[657] =>
[658] => throw new \Exception($message, $e->getCode());
[659] => }
[660] => } else {
[661] => error_log(print_r($stmt, 1));
[662] => error_log($this->debugSql($origSql, $params, $paramTypes));
[663] => }
[664] =>
[665] => return $stmt;
[666] => }
[667] =>
[668] => /**
[669] => * Bind a parameter value to the current prepared statement.
[670] => *
[671] => * @param string|int $param The parameter index or name.
[672] => * @param mixed $value The value to bind.
[673] => * @param int|null $type The PDO type constant, or null for auto-detection.
[674] => *
[675] => * @return void
[676] => */
[677] => public function bind(string|int $param, mixed $value, ?int $type = null): void {
[678] => // TODO: bindValue() is PDO-only; store bindings for later use if needed
[679] => }
[680] => }
)
)