0Pricing
PHP Academy · Lektion

Eine einfache PHP-Erweiterung in C schreiben

Ihre eigene native Erweiterung erstellen und laden

Eine einfache PHP-Erweiterung in C schreiben ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Nativer Code in PHP

Wenn reines PHP zu langsam ist oder Sie eine C-Bibliothek anbinden müssen, schreiben Sie eine PHP-Erweiterung in C gegen die Zend API. Die Erweiterung stellt native Funktionen und Klassen bereit, die PHP direkt aufruft – ohne VM-Overhead.

In dieser Lektion erstellen Sie durchgängig eine minimale hello-Erweiterung: Gerüst, Funktion, Build, Laden und Test.

Die Build-Toolchain

Erweiterungen werden mit PHPs phpize erstellt. Dabei wird ein autoconf-Build mit den Headern Ihrer installierten PHP-Version vorbereitet. Sie benötigen php-dev/php-devel (stellt phpize und php-config bereit) sowie einen C-Compiler und make.

# Install build prerequisites (Debian/Ubuntu)
sudo apt install php-dev build-essential

# Confirm the tools exist
phpize --version
php-config --extension-dir   # where the .so will be installed

config.m4

Jede Erweiterung benötigt eine config.m4, die ein Build-Flag registriert und die Quelldateien angibt. phpize verwendet diese Datei, um das Konfigurationsskript zu erzeugen.

dnl config.m4 for the 'hello' extension
PHP_ARG_ENABLE([hello],
  [whether to enable hello support],
  [AS_HELP_STRING([--enable-hello], [Enable hello])],
  [no])

if test "$PHP_HELLO" != "no"; then
  PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)
fi

Header der Erweiterung

Der C-Quellcode bindet die Zend/PHP-Header ein und deklariert den Moduleintrag. php.h bindet die zentrale API ein; ext/standard/info.h wird für die Ausgabe von phpinfo() verwendet. Jede Erweiterung definiert einen zend_module_entry.

/* hello.c — includes */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "hello_arginfo.h"   /* generated from stub */

Arginfo-Stubs

Modernes PHP erzeugt Argumentmetadaten aus einer .stub.php-Datei. Sie schreiben die Funktionssignatur in einer PHP-ähnlichen Syntax; gen_stub.php erzeugt daraus hello_arginfo.h. So bleiben Reflection- und Typinformationen korrekt.

<?php
// hello.stub.php — describes the native function's signature
/** @generate-class-entries */

function hello_greet(string $name): string {}
?>

Die Funktion implementieren

Eine native Funktion ist eine mit PHP_FUNCTION gekennzeichnete C-Funktion. Eingehende Argumente werden mit ZEND_PARSE_PARAMETERS-Makros eingelesen, Rückgabewerte mit RETURN_*-Makros zurückgegeben. Hier erstellen wir eine Begrüßungszeichenfolge.

/* hello.c — the native function */
PHP_FUNCTION(hello_greet)
{
    char *name;
    size_t name_len;

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_STRING(name, name_len)
    ZEND_PARSE_PARAMETERS_END();

    /* Build "Hello, <name>!" into a new zend_string */
    zend_string *result = strpprintf(0, "Hello, %s!", name);
    RETURN_STR(result);   /* hands ownership to the engine */
}

Der Moduleintrag

Der zend_module_entry führt alle Bestandteile zusammen: Name, Version, die Funktionstabelle (aus den Arginfo-Daten) und die Lebenszyklus-Hooks (MINIT, RINIT, MINFO). ZEND_GET_MODULE exportiert das Einstiegssymbol, nach dem der Loader sucht.

/* hello.c — module wiring */
zend_module_entry hello_module_entry = {
    STANDARD_MODULE_HEADER,
    "hello",                 /* extension name */
    ext_functions,           /* function table from arginfo */
    NULL,                    /* MINIT  (module startup)  */
    NULL,                    /* MSHUTDOWN */
    NULL,                    /* RINIT  (per-request)     */
    NULL,                    /* RSHUTDOWN */
    PHP_MINFO(hello),        /* phpinfo section */
    "0.1.0",
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif

Speicher: emalloc vs malloc

Verwenden Sie innerhalb einer Erweiterung für Speicher, der nur für die Dauer einer Anfrage benötigt wird, emalloc/efree (vom Zend Memory Manager verwaltet und am Ende der Anfrage freigegeben) – nicht das rohe malloc. Für persistente Allokationen, die mehrere Anfragen überdauern, verwenden Sie pemalloc. Wenn Sie einen zend_string mit RETURN_STR zurückgeben, geht dessen Besitz an die Engine über, die ihn freigibt.

/* Request-scoped buffer the engine will clean up on error/shutdown */
char *buf = emalloc(64);
/* ... use buf ... */
efree(buf);

/* Persistent allocation surviving the request (rare) */
/* char *cfg = pemalloc(128, 1);  ...  pefree(cfg, 1); */

Erstellung

Der klassische Build in drei Schritten: phpize zum Anlegen der Grundstruktur, ./configure mit Ihrem Aktivierungs-Flag und anschließend make. Denken Sie daran, zuerst gen_stub.php auszuführen, um den Arginfo-Header zu erzeugen.

# Generate arginfo from the stub
php /path/to/php-src/build/gen_stub.php hello.stub.php

# Scaffold + configure + compile
phpize
./configure --enable-hello
make

# Result lands in modules/hello.so
ls -la modules/hello.so

Laden und Testen

Laden Sie die kompilierte .so-Datei mit -d extension=... (oder fügen Sie sie einer ini-Datei hinzu). Rufen Sie die native Funktion anschließend aus PHP genau wie eine eingebaute Funktion auf. So sieht Ihr Test- bzw. Überprüfungsskript aus, sobald die Erweiterung installiert ist.

<?php
// After:  php -d extension=./modules/hello.so test.php
if (!extension_loaded('hello')) {
    fwrite(STDERR, "hello extension not loaded\n");
    exit(1);
}

echo hello_greet('Zend') . PHP_EOL;   // Hello, Zend!
var_dump(extension_loaded('hello'));  // bool(true)
?>

Wann Sie eine solche Erweiterung schreiben sollten (und wann nicht)

Native Erweiterungen verursachen zusätzlichen Wartungsaufwand: Speicherfehler in C, erneute Builds für jede PHP-Minor-Version und ABI-Inkompatibilitäten. Bevor Sie nativen Code schreiben, sollten Sie FFI in Betracht ziehen (damit können Sie C-Bibliotheken aus PHP aufrufen, ohne eine Erweiterung zu kompilieren) oder PHP-Code direkt optimieren. Entscheiden Sie sich für eine C-Erweiterung, wenn Sie maximale Geschwindigkeit, eine tiefe Integration in die Engine oder eine saubere Anbindung einer komplexen C-Bibliothek benötigen.

<?php
// FFI alternative: call a C library directly, no extension build
$ffi = FFI::cdef(
    "int abs(int);",   // declare the symbol
    "libc.so.6"
);
echo $ffi->abs(-42) . PHP_EOL;   // 42
?>

Kurzer Check

Welcher Allocator sollte innerhalb einer Erweiterung Speicher halten, der nur für die Dauer einer Anfrage benötigt wird?

Zusammenfassung

Sie haben eine minimale C-Erweiterung erstellt: config.m4 registriert den Build, eine .stub.php-Datei erzeugt die Arginfo-Daten, PHP_FUNCTION implementiert die Logik, liest Argumente mit ZEND_PARSE_PARAMETERS ein und gibt mit RETURN_STR einen Wert zurück, und ein zend_module_entry verbindet die Lebenszyklus-Hooks. Erstellen Sie den Build mit phpize → configure → make, laden Sie die .so-Datei und testen Sie die Erweiterung aus PHP heraus. Verwenden Sie emalloc für anfragebezogenen Speicher – und ziehen Sie FFI in Betracht, bevor Sie sich für nativen Code entscheiden.

Häufig gestellte Fragen

Ist die Lektion „Eine einfache PHP-Erweiterung in C schreiben“ kostenlos?

Ja — der vollständige Text von „Eine einfache PHP-Erweiterung in C schreiben“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Eine einfache PHP-Erweiterung in C schreiben“?

Ihre eigene native Erweiterung erstellen und laden Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um PHP Academy zu starten?

Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Eine einfache PHP-Erweiterung in C schreiben“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?

Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. So funktioniert die Zend Engine
  2. Speicherverwaltung und Garbage Collection
  3. OPcache und JIT-Kompilierung
  4. Eine einfache PHP-Erweiterung in C schreiben
← Zurück zu PHP Academy