Documentation

Connection
in package
implements Checkpointable Uses Interaction, CanCheckpoint

Interfaces, Classes and Traits

Checkpointable
Contract for classes that want checkpoint/restore of their state.

Table of Contents

CONNECT_TIMEOUT_SECONDS  = 5
Seconds a single connect attempt may take before failing over.
CONNECTION_LOSS_ERROR_CODES  = [ 1047, // WSREP has not yet prepared node for application use 2002, // Can't connect through socket / connection refused 2003, // Can't connect to server on host 2006, // Server has gone away 2013, ]
Client/server error codes meaning this connection cannot serve the statement (endpoint moved by the mesh, node died, network blip, or a Galera node refusing service while desynced as an SST/IST donor).
RECONNECT_BACKOFF_CAP_US  = 2000000
RECONNECT_BACKOFF_STEP_US  = 400000
Reconnect backoff grows with the attempt (attempt x step, capped) so the budget spans a realistic failover window instead of burning out in milliseconds while the mesh is still promoting a healthy node.
RETRY_BACKOFF_MAX_US  = 50000
RETRY_BACKOFF_MIN_US  = 10000
Randomized backoff bounds (microseconds) slept between retry attempts.
RETRYABLE_ERROR_CODES  = [ 1213, // Deadlock found when trying to get lock 1205, ]
MySQL/MariaDB error codes that are safe to retry: the server has already rolled the offending statement back, so re-running it does not risk double-applying it. These are the transient contention errors typical of busy single-node and cluster (Galera) setups.
RETRYABLE_SQL_STATES  = ["40001"]
SQLSTATE values that are safe to retry (e.g. Galera certification conflicts).
$booter  : ZubZet
$callingModel  : Model|null
$connectTimeout  : int
$insertId  : int|string|null
$lastConnect  : int
$lastHeartbeat  : int
$maxRetries  : int
$queryBuilderConnection  : Connection
$result  : null|bool|mysqli_result
$conn  : mysqli
$database  : string|null
$password  : string|null
$persistent  : bool
$stmt  : mysqli_stmt
$user  : string|null
__construct()  : mixed
__destruct()  : mixed
Closes the database connection on exit
assertConnection()  : mixed
checkIfExists()  : bool
Checks if a value exists in a table.
checkIfUnique()  : bool
Checks if a value is already in a table. Can also ignore a dataset.
checkpointCurrentState()  : Checkpoint
Snapshot selected properties into a Checkpoint for later restore()
countResults()  : int
Returns the number of results in the last query
countTableEntries()  : int
Returns the number of datasets in a table
disconnect()  : void
Disconnect from the database
exec()  : Connection
Executes a query as prepared statement
execQuery()  : Connection
Executes a CakePHP Query object using ZubZet`s own value binder to extract the SQL and bindings, then executing it as a prepared statement
executeMultiQuery()  : bool
getDatabaseConnection()  : mysqli
getFullTable()  : array<string|int, array<string|int, mixed>>
Selects a full table or specified fields of it and returns the result as two dimensional array
getInsertId()  : int|string|null
Returns the id of the last inserted element
getTableWhere()  : array<string|int, array<string|int, mixed>>
Selects a full table of specified fields of it filtered with an additional where statement. It returns the result as two dimensional array
heartbeat()  : bool
Run a very lightweight query to keep the connection alive.
mergeAsGroup()  : array<string|int, array<string|int, mixed>>
Converts the result of the last query into a grouped array
resultToArray()  : array<string|int, array<string|int, mixed>>
Converts the result of the last query into an array and returns it
resultToLine()  : array<string|int, mixed>
Returns one line of the last query
switchUser()  : void
checkpointablePropertyNames()  : array<string|int, string>
attemptStatement()  : array<string|int, mixed>|null
Makes one attempt at the statement: reconnect when asked to, prepare, bind, execute. Returns null on success and a failure descriptor (see failure()) otherwise.
connect()  : mixed
execWithRecovery()  : void
Runs the statement until it succeeds, recovering two failure classes within the shared db_max_retries budget:
failure()  : array<string|int, mixed>
Failure descriptor for one statement attempt, carrying what the recovery decision needs and the ready-to-throw exception with the historical prefix: "SQL Error" for connect and prepare failures, "SQL Execution Error" for execute failures.
isRetryable()  : bool
Classifies an error as retryable. Retries are limited to transient contention errors where the server already discarded the statement, making a re-run safe. Pure decision, no side effects.
pingConnection()  : bool
Sends a lightweight query to check whether an already-established connection is still responding. Assumes a connection has been opened.
reconnectBackoffUs()  : int
Attempt-scaled backoff slept before a reconnect attempt.
shouldReconnect()  : bool
Whether a just-failed query should be recovered by reconnecting: there must be retry budget left and the error must mean the connection itself is gone.
shouldRetry()  : bool
Whether a just-failed query should be retried: there must be retry budget left and the error must be a transient, cluster-related one.
sqlStateOf()  : string|null
Reads the SQLSTATE from a thrown mysqli exception, where mysqli_sql_exception::getSqlState() only exists on PHP 8.1+.

Constants

CONNECT_TIMEOUT_SECONDS

Seconds a single connect attempt may take before failing over.

private mixed CONNECT_TIMEOUT_SECONDS = 5

CONNECTION_LOSS_ERROR_CODES

Client/server error codes meaning this connection cannot serve the statement (endpoint moved by the mesh, node died, network blip, or a Galera node refusing service while desynced as an SST/IST donor).

private mixed CONNECTION_LOSS_ERROR_CODES = [ 1047, // WSREP has not yet prepared node for application use 2002, // Can't connect through socket / connection refused 2003, // Can't connect to server on host 2006, // Server has gone away 2013, ]

Recovered by reconnecting through the configured endpoint, which routes to a usable node, and re-preparing. For 1047 the refusing node never executed the statement, so that re-run is always safe; the lost-acknowledgment caveat only applies to 2006/2013.

RECONNECT_BACKOFF_CAP_US

private mixed RECONNECT_BACKOFF_CAP_US = 2000000

RECONNECT_BACKOFF_STEP_US

Reconnect backoff grows with the attempt (attempt x step, capped) so the budget spans a realistic failover window instead of burning out in milliseconds while the mesh is still promoting a healthy node.

private mixed RECONNECT_BACKOFF_STEP_US = 400000

RETRY_BACKOFF_MAX_US

private mixed RETRY_BACKOFF_MAX_US = 50000

RETRY_BACKOFF_MIN_US

Randomized backoff bounds (microseconds) slept between retry attempts.

private mixed RETRY_BACKOFF_MIN_US = 10000

RETRYABLE_ERROR_CODES

MySQL/MariaDB error codes that are safe to retry: the server has already rolled the offending statement back, so re-running it does not risk double-applying it. These are the transient contention errors typical of busy single-node and cluster (Galera) setups.

private mixed RETRYABLE_ERROR_CODES = [ 1213, // Deadlock found when trying to get lock 1205, ]

RETRYABLE_SQL_STATES

SQLSTATE values that are safe to retry (e.g. Galera certification conflicts).

private mixed RETRYABLE_SQL_STATES = ["40001"]

Properties

$callingModel

public Model|null $callingModel = null

A reference to the model that is currently handling the query, if any

$insertId

public int|string|null $insertId

Last insert id

$queryBuilderConnection

public Connection $queryBuilderConnection

$result

public null|bool|mysqli_result $result

Result of the last query

Methods

__construct()

public __construct() : mixed
Return values
mixed

__destruct()

Closes the database connection on exit

public __destruct() : mixed
Return values
mixed

assertConnection()

public assertConnection() : mixed
Return values
mixed

checkIfExists()

Checks if a value exists in a table.

public checkIfExists(string $table, string $field, mixed $value) : bool

Table and field names are inserted unescaped. Check your input.

Parameters
$table : string

Name of the table to check in

$field : string

Name of the field in that a value should exist

$value : mixed

Value to check for

Return values
bool

True when exists

checkIfUnique()

Checks if a value is already in a table. Can also ignore a dataset.

public checkIfUnique(string $table, string $field, mixed $value[, string $ignoreField = null ][, string $ignoreValue = null ]) : bool

Table and field names are inserted unescaped. Check your input.

Parameters
$table : string

Name of the table to check in

$field : string

Field to check in

$value : mixed

Value to check for

$ignoreField : string = null

field of a dataset to ignore

$ignoreValue : string = null

value of the in the argument before defined field of the dataset to ignore

Return values
bool

True when not exists

checkpointCurrentState()

Snapshot selected properties into a Checkpoint for later restore()

public checkpointCurrentState([array<string|int, mixed>|null $properties = null ][, string|null $attributeClass = null ]) : Checkpoint
Parameters
$properties : array<string|int, mixed>|null = null
$attributeClass : string|null = null
Return values
Checkpoint

countResults()

Returns the number of results in the last query

public countResults() : int
Return values
int

Number of results in the last query

countTableEntries()

Returns the number of datasets in a table

public countTableEntries(string $table) : int
Parameters
$table : string

Name of the table in the database

Return values
int

Number of datasets in the specified table

disconnect()

Disconnect from the database

public disconnect() : void
Return values
void

exec()

Executes a query as prepared statement

public exec(string $query) : Connection
Parameters
$query : string

Query written as prepared statement (that thing with the question marks as placeholders)

Return values
Connection

Returning this for chaining

execQuery()

Executes a CakePHP Query object using ZubZet`s own value binder to extract the SQL and bindings, then executing it as a prepared statement

public execQuery(Query $query) : Connection
Parameters
$query : Query

The CakePHP Query object to execute

Return values
Connection

Returning this for chaining

executeMultiQuery()

public executeMultiQuery(string $query[, bool $throwOnFailure = true ]) : bool
Parameters
$query : string
$throwOnFailure : bool = true
Return values
bool

getDatabaseConnection()

public getDatabaseConnection() : mysqli
Return values
mysqli

getFullTable()

Selects a full table or specified fields of it and returns the result as two dimensional array

public getFullTable(string $table[, string $fields = "*" ]) : array<string|int, array<string|int, mixed>>
Parameters
$table : string

Name of the table in the database

$fields : string = "*"

Fields to select. Formatted as in an SQL query ("*", "a, b, c"...)

Return values
array<string|int, array<string|int, mixed>>

A two dimensional array with the results of the select statement

getInsertId()

Returns the id of the last inserted element

public getInsertId() : int|string|null
Return values
int|string|null

Id of the last inserted element

getTableWhere()

Selects a full table of specified fields of it filtered with an additional where statement. It returns the result as two dimensional array

public getTableWhere(string $table[, string $fields = "*" ][, string $where = "" ][, string $types = "" ][, array<string|int, mixed> $values = [] ]) : array<string|int, array<string|int, mixed>>
Parameters
$table : string

Name of the table in the database

$fields : string = "*"

Fields to select. Formatted as in a SQL query ("*", "a, b, c"...)

$where : string = ""

The where statement in the query. Formatted as in a SQL query (a = 4 AND c = 4...);

$types : string = ""

String with the types. Conform to prepared statements ("ssis")

$values : array<string|int, mixed> = []

The values to insert in the prepared statement

Return values
array<string|int, array<string|int, mixed>>

two dimensional array with table data

heartbeat()

Run a very lightweight query to keep the connection alive.

public heartbeat([bool $waitForTimeout = true ][, int $timeoutBuffer = 30 ]) : bool
Parameters
$waitForTimeout : bool = true

Only ping if no heartbeat happened within the timeout window

$timeoutBuffer : int = 30

Seconds subtracted from the timeout before a ping is forced

Tags
deprecated

since 1.2.0 The connection now self-heals on use via assertConnection(), so a manual keep-alive loop is no longer necessary. Simply remove your heartbeat() calls and let queries transparently (re)connect as needed. Kept for backward compatibility with existing worker loops.

Return values
bool

Whether a live connection responded. False when no connection has been opened yet (lazy loading) or the ping failed.

mergeAsGroup()

Converts the result of the last query into a grouped array

public mergeAsGroup(string $groupBy[, string $subElement = null ]) : array<string|int, array<string|int, mixed>>
Parameters
$groupBy : string

The field, by which the array is grouped by

$subElement : string = null

If set, the only a sub element of the grouped element is returned

Return values
array<string|int, array<string|int, mixed>>

Results of the last query as two dimensional array with the index as thr groupBy value

resultToArray()

Converts the result of the last query into an array and returns it

public resultToArray([mixed $out = [] ]) : array<string|int, array<string|int, mixed>>
Parameters
$out : mixed = []
Return values
array<string|int, array<string|int, mixed>>

Results of the last query as two dimensional array

resultToLine()

Returns one line of the last query

public resultToLine() : array<string|int, mixed>
Return values
array<string|int, mixed>

Line of the last result

switchUser()

public switchUser(string $user, string $password) : void
Parameters
$user : string
$password : string
Return values
void

checkpointablePropertyNames()

protected checkpointablePropertyNames([string|null $attributeClass = IncludeInCheckpoint::class ]) : array<string|int, string>
Parameters
$attributeClass : string|null = IncludeInCheckpoint::class
Return values
array<string|int, string>

Filtered by $attributeClass when given, else all non-static instance properties.

attemptStatement()

Makes one attempt at the statement: reconnect when asked to, prepare, bind, execute. Returns null on success and a failure descriptor (see failure()) otherwise.

private attemptStatement(string $query, array<string|int, mixed> $bindArgs, bool $reconnect) : array<string|int, mixed>|null

mysqli reports failures by throwing under PHP 8.1+ strict reporting and by return value on PHP 8.0; both are captured here, reading the SQLSTATE from the handle that recorded it.

Parameters
$query : string
$bindArgs : array<string|int, mixed>
$reconnect : bool
Return values
array<string|int, mixed>|null

connect()

private connect() : mixed
Return values
mixed

execWithRecovery()

Runs the statement until it succeeds, recovering two failure classes within the shared db_max_retries budget:

private execWithRecovery(string $query, array<string|int, mixed> $bindArgs) : void
  • Transient contention (RETRYABLE_ERROR_CODES): the server already rolled the statement back, so re-running it on the kept connection after a short randomized backoff is safe.
  • Connection loss (CONNECTION_LOSS_ERROR_CODES): reconnect through the configured endpoint, which routes to a usable node, then re-prepare and re-run. Documented caveat: if a write was applied but the connection died before the acknowledgment, the re-run applies it again; every exec() is auto-committed, so the exposure is a single statement.
Parameters
$query : string
$bindArgs : array<string|int, mixed>
Return values
void

failure()

Failure descriptor for one statement attempt, carrying what the recovery decision needs and the ready-to-throw exception with the historical prefix: "SQL Error" for connect and prepare failures, "SQL Execution Error" for execute failures.

private failure(string $errorPrefix, int $errorCode, string|null $sqlState, string $message, string $query[, mysqli_sql_exception|null $error = null ]) : array<string|int, mixed>
Parameters
$errorPrefix : string
$errorCode : int
$sqlState : string|null
$message : string
$query : string
$error : mysqli_sql_exception|null = null
Return values
array<string|int, mixed>

isRetryable()

Classifies an error as retryable. Retries are limited to transient contention errors where the server already discarded the statement, making a re-run safe. Pure decision, no side effects.

private isRetryable(int $errorCode, string|null $sqlState) : bool
Parameters
$errorCode : int
$sqlState : string|null
Return values
bool

pingConnection()

Sends a lightweight query to check whether an already-established connection is still responding. Assumes a connection has been opened.

private pingConnection() : bool
Return values
bool

True if the server answered, false if the connection is dead

reconnectBackoffUs()

Attempt-scaled backoff slept before a reconnect attempt.

private reconnectBackoffUs(int $attempt) : int
Parameters
$attempt : int
Return values
int

shouldReconnect()

Whether a just-failed query should be recovered by reconnecting: there must be retry budget left and the error must mean the connection itself is gone.

private shouldReconnect(int $attempt, int $errorCode) : bool
Parameters
$attempt : int
$errorCode : int
Return values
bool

shouldRetry()

Whether a just-failed query should be retried: there must be retry budget left and the error must be a transient, cluster-related one.

private shouldRetry(int $attempt, int $errorCode, string|null $sqlState) : bool
Parameters
$attempt : int
$errorCode : int
$sqlState : string|null
Return values
bool

sqlStateOf()

Reads the SQLSTATE from a thrown mysqli exception, where mysqli_sql_exception::getSqlState() only exists on PHP 8.1+.

private sqlStateOf(mysqli_sql_exception $error) : string|null

Exceptions without it are classified by error code alone; failures reported by return value never reach this method, their SQLSTATE is read off the failing handle in attemptStatement().

Parameters
$error : mysqli_sql_exception
Return values
string|null

Search results