Skip to content

plphp

Embed PHP 8 as an untrusted PostgreSQL procedural language

Overview

PackageVersionCategoryLicenseLanguage
plphp2.6LANGPostgreSQLC
IDExtensionBinLibLoadCreateTrustRelocSchema
3170plphpNoYesNoYesNoNo-
Relatedplruby plperl plpython3u pllua plv8 jsonb_plphp hstore_plphp bytea_plphp
Depended Bybytea_plphp hstore_plphp jsonb_plphp

Uses non-ZTS PHP embed. EL8/EL9 RPMs require the PHP 8.2/8.3 module streams respectively; DEBs pin the matching PHP embed runtime for each OS. No preload or fixed schema. The three optional transforms are not included in this package.

Version

TypeRepoVersionPG VerPackageDeps
EXTPIGSTY2.61817161514plphp-
RPMPIGSTY2.61817161514plphp_$vphp-embedded
DEBPIGSTY2.61817161514postgresql-$v-plphplibphp-embed
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
d13.x86_64
d13.aarch64
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
u22.x86_64
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
u22.aarch64
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
u24.x86_64
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
u24.aarch64
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
PIGSTY 2.6
u26.x86_64
u26.aarch64

Build

You can build the RPM / DEB packages for plphp using pig build:

pig build pkg plphp         # build RPM / DEB packages

Install

You can install plphp directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:

pig repo add pgsql -u          # Add repo and update cache

Install the extension using pig or apt/yum/dnf:

Install
pig install plphp;          # Install for current active PG version
pig
pig ext install -y plphp -v 18  # PG 18
pig ext install -y plphp -v 17  # PG 17
pig ext install -y plphp -v 16  # PG 16
pig ext install -y plphp -v 15  # PG 15
pig ext install -y plphp -v 14  # PG 14
dnf
dnf install -y plphp_18       # PG 18
dnf install -y plphp_17       # PG 17
dnf install -y plphp_16       # PG 16
dnf install -y plphp_15       # PG 15
dnf install -y plphp_14       # PG 14
apt
apt install -y postgresql-18-plphp   # PG 18
apt install -y postgresql-17-plphp   # PG 17
apt install -y postgresql-16-plphp   # PG 16
apt install -y postgresql-15-plphp   # PG 15
apt install -y postgresql-14-plphp   # PG 14

Create Extension:

CREATE EXTENSION plphp;

Usage

Sources:

plphp embeds PHP as an untrusted PostgreSQL procedural language for functions, procedures, triggers, event triggers, and anonymous blocks. Use it only when PHP APIs are worth running with the operating-system privileges of the PostgreSQL server process; it is not a sandboxed language.

Core Workflow

CREATE EXTENSION plphp;

CREATE FUNCTION php_square(integer)
RETURNS integer
LANGUAGE plphp
AS $$
    return $args[0] * $args[0];
$$;

SELECT php_square(12);

PL/php 2.6 supports PHP 8.1 through 8.4 using the embed SAPI without ZTS and PostgreSQL 11 through 18. Installation and creation require a superuser because the language is deliberately untrusted.

Main Interfaces

  • spi_exec(...), spi_prepare(...), spi_exec_prepared(...), spi_query(...), and cursor helpers access PostgreSQL through SPI.
  • return_next() emits rows from set-returning functions.
  • spi_commit() and spi_rollback() provide transaction control inside procedures.
  • subtransaction(...) creates a catchable subtransaction boundary.
  • $_TD exposes trigger and event-trigger context.
  • $_SHARED is session-global storage, while $_SD is private per-function session storage.
  • plphp.on_init, plphp.start_proc, and plphp_modules initialize a session interpreter.

The optional jsonb_plphp, hstore_plphp, and bytea_plphp extensions add native transforms. A function must declare TRANSFORM FOR TYPE ... to use a transform; installing a companion does not change every PL/php function automatically.

Security and Operations

A PL/php function can read or write files, open network connections, invoke PHP facilities, and affect anything accessible to the PostgreSQL operating-system account. Only grant function ownership and creation rights to roles trusted like a server administrator. Apply normal SECURITY DEFINER and search_path hardening when a privileged wrapper is unavoidable.

SPI query text, dynamic identifiers, session initialization code, loaded modules, and persistent interpreter state all require review. Long-running PHP code blocks a PostgreSQL backend, and memory retained in $_SHARED or $_SD lasts for the session. Use prepared statements for untrusted values, bound resource use, test cancellation/error paths, and recycle sessions when application code retains excessive state.

Version 2.6 adds per-function $_SD and the binary-safe bytea_plphp transform. PostgreSQL tracks the control version as 2.6 while the source distribution is 2.6.0.

Was this page helpful?