Unlock Python in PHP: Install and Use the phpy Extension

This article introduces phpy, a PHP‑Python bridge library from Swoole, explains its purpose of filling gaps in the PHP ecosystem, provides step‑by‑step compilation and installation instructions, and demonstrates how to call Python packages, handle callbacks, and build GUI or AI applications from PHP code.

21CTO
21CTO
21CTO
Unlock Python in PHP: Install and Use the phpy Extension
phpy is an open‑source PHP‑Python calling library developed by Swoole (Shiwotech) to address gaps in the PHP ecosystem.

Background

Swoole, the team behind the coroutine product Swoole, created phpy to enable PHP to import and use Python packages, including popular AI libraries such as PyTorch, Transformers, TensorFlow, NumPy, Pandas, Scikit‑Learn, as well as GUI libraries like PyQt and wxPython.

GitHub: https://github.com/swoole/phpy

Do not use phpy in short‑lived environments like php‑fpm/apache; frequent module import/export can consume many resources.

Compilation and Installation

phpy can be built as a PHP extension or as a Python C module, allowing PHP code to call Python libraries and Python code to call PHP classes and functions.

When used as a Python module, it depends on the PHP embed SAPI; ensure libphp.so exists in the PHP directory.
ll /opt/php-8.1/lib/libphp.so‑rwxr‑x‑r‑x 1 htf htf 39397224 11月 30 19:25 /opt/php-8.1/lib/libphp.so*

Compilation Dependencies

Python 3.10+ (conda recommended)

PHP 8.1+

Python will be installed under /opt/anaconda3 with binaries, headers, and libraries placed accordingly. /opt/anaconda3/bin/python – Python executable /opt/anaconda3/include/python3.11 – Header files /opt/anaconda3/lib/python3.11 – Dynamic libraries

Update /etc/ld.so.conf.d/conda.conf to include /opt/anaconda3/lib and /opt/php-8.1/lib, then run ldconfig to ensure libpython3.11.so and libphp.so are discoverable.

sudo ldconfig -p | grep php
sudo ldconfig -p | grep python

As a PHP Extension

Check config.m4 for the correct Python path; if it differs from /opt/anaconda3, modify it.

cd phpy
phpize
./configure
make install

After installation, add extension=phpy.so to php.ini and verify with php -m and php --ri phpy.

As a Python Module

cmake .
make -j

The build produces tests/lib/phpy.so, which can be imported directly in Python.

<span class="keyword">import</span> phpy

Usage

Importing Python Modules

<span class="variable">$os</span> = <span class="class">PyCore</span>::<span class="method">import</span>('os');

Calling Functions

<span class="variable">$uname</span> = <span class="variable">$os</span>-><span class="method">uname</span>();

Reading Attributes

<span class="keyword">echo</span> <span class="variable">$uname</span>->sysname;

Modifying Load Paths

Use PyCore::import('sys')->path->append('/workspace') to add custom directories.

Append /workspace to sys.path.

Import app.user which will be found via the updated path.

Built‑in Methods

PyCore::str()

– convert object to string

PyCore::repr()
PyCore::type()

– get object type PyCore::locals() – get local variables PyCore::globals() – get global variables PyCore::hash() – get hash value PyCore::hasattr() – check attribute existence PyCore::id() – get internal ID PyCore::len() – get length PyCore::dir() – list attributes and methods PyCore::int() – construct integer PyCore::float() – construct float PyCore::fn() – construct callable PyCore::scalar() – convert PyObject to PHP scalar types

Built‑in Classes

PyObject

– base class for all types PyDict – dictionary, maps to PHP associative array PyList – list, maps to PHP indexed array PyTuple – immutable list PyStr – string PyModule – Python package, subclass of

PyObject

Named Parameters

phpy supports named parameters; positional arguments must precede named ones.

kwargs($a, $b, $c, name: 'hello', world: 'rango');

Callback Functions

PHP callables can be passed to Python as callbacks using PyCore::fn().

<span class="variable">$m</span> = <span class="class">PyCore</span>::import('app.user');
<span class="variable">$uuid</span> = uniqid();
<span class="variable">$rs</span> = <span class="variable">$m</span>->test_callback(
    <span class="class">PyCore</span>::fn(function ($namespace) use ($uuid) {
        var_dump($namespace);
        return $uuid;
    })
);

Real‑World Examples

GUI with Tkinter

PHP code can create a Tkinter window, add a button, and bind a PHP closure as the click handler.

<?php
$tkinter = PyCore::import('tkinter');
$root = $tkinter->Tk();
$root->title('我的窗口');
$root->geometry('500x500');
$root->resizable(False, False);
$button = $tkinter->Button($root, text: 'Click Me!!', command: PyCore::fn(function () {
    var_dump(func_get_args());
    echo 'click me!!' . PHP_EOL;
}));
$button->pack();
$tkinter->mainloop();
?>

Sentiment Analysis with Transformers

Using the transformers library from PHP to run a distilled BERT sentiment model.

<?php
$transformers = PyCore::import('transformers');
$os = PyCore::import('os');
$os->environ->__setitem__('https_proxy', getenv('https_proxy'));
$sentiment = $transformers->pipeline(model: "lxyuan/distilbert-base-multilingual-cased-sentiments-student", top_k: null);
$result = $sentiment("I love this movie and i would watch it again and again!");
var_dump(PyCore::scalar($result));
?>
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonPHPExtensionInteropphpy
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.