PHP Conference Nagoya 2025

pg_last_error

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

pg_last_error特定の接続から直近のエラーメッセージ文字列を取得する

説明

pg_last_error(?PgSql\Connection $connection = null): string

pg_last_error() は、指定した connection から直近のエラーメッセージを返します。

エラーメッセージは、内部的な PostgreSQL(libpq) 関数コールにより 上書きされる可能性があります。PostgreSQL モジュール関数の中で複数の エラーが発生した場合には、この関数は適切なエラーメッセージを返さない 可能性があります。

エラー処理を改善するために pg_result_error()pg_result_error_field()pg_result_status() および pg_connection_status() を使用ください。

注意:

この関数は、以前は pg_errormessage() と呼ばれていました。

パラメータ

connection

PgSql\Connection クラスのインスタンス。 connectionnull, の場合、デフォルトの接続を使います。 デフォルトの接続とは、pg_connect() または pg_pconnect() によって確立された直近の接続です。

警告

PHP 8.1.0 以降では、デフォルトの接続を使うことは推奨されなくなりました。

戻り値

指定した connection の直近のエラーメッセージを 含む文字列を返します。

変更履歴

バージョン 説明
8.1.0 connection は、PgSql\Connection クラスのインスタンスを期待するようになりました。 これより前のバージョンでは、リソース を期待していました。
8.0.0 connection は、nullable になりました。

例1 pg_last_error() の例

<?php
$dbconn
= pg_connect("dbname=publisher") or die("接続できませんでした");

// 失敗するクエリ
$res = pg_query($dbconn, "select * from doesnotexist");

echo
pg_last_error($dbconn);
?>

参考

add a note

User Contributed Notes 1 note

up
5
Tamas Bolner
14 years ago
From a practical view there are two types of error messages when using transactions:

-"Normal" errors: in this case, the application should stop the current process and show an error message to the user.

-Deadlock errors. This shows that the deadlock detection process of PostgreSQL found a circle of dependency, and broke it by rolling back the transaction in one of the processes, which gets this error msg. In this case, the application should not stop, but repeat the transaction.

I found no discrete way to find out which case are we dealing with. This interface doesn't support error codes, so we have to search for patterns in the message text.

Here is an example for PostgreSQL database connection class. It throws a PostgresException on "normal" errors, and DependencyException in the case of a broken deadlock, when we have to repeat the transaction.

postgres.php:
<?php
class PostgresException extends Exception {
function
__construct($msg) { parent::__construct($msg); }
}

class
DependencyException extends PostgresException {
function
__construct() { parent::__construct("deadlock"); }
}

class
pg {
public static
$connection;

private static function
connect() {
self::$connection = @pg_connect("dbname=foodb user=foouser password=foopasswd");
if (
self::$connection === FALSE) {
throw(new
PostgresException("Can't connect to database server."));
}
}

public static function
query($sql) {
if (!isset(
self::$connection)) {
self::connect();
}

$result = @pg_query(self::$connection, $sql);
if (
$result === FALSE) {
$error = pg_last_error(self::$connection);
if (
stripos($error, "deadlock detected") !== false) throw(new DependencyException());

throw(new
PostgresException($error.": ".$sql));
}

$out = array();
while ( (
$d = pg_fetch_assoc($result)) !== FALSE) {
$out[] = $d;
}

return
$out;
}
}
?>

It should be used in this way:

test.php:
<?php
include("postgres.php");

do {
$repeat = false;
try {
pg::query("begin");

...

$result = pg::query("SELECT * FROM public.kitten");

...

pg::query("commit");
}
catch (
DependencyException $e) {
pg::query("rollback");
$repeat = true;
}
} while (
$repeat);
?>

The normal errors should be caught at the frontend.

Tamas
To Top