Разработка PHP-расширений позволяет интегрировать в PHP высокопроизводительный C-код для решения специфических задач. Рассмотрим процесс создания расширения от начала до конца.
# Для Debian/Ubuntu
sudo apt install php-dev php-cli autoconf automake libtool re2c
# Для CentOS/RHEL
sudo yum install php-devel php-cli autoconf automake libtool re2c
PHP предоставляет утилиту ext_skel
для создания заготовки:
php ./ext_skel.php --extname=my_extension
cd my_extension
Структура сгенерированного проекта:
my_extension/
├── config.m4 # Конфигурация сборки
├── php_my_extension.h # Заголовочный файл
├── my_extension.c # Основной исходный код
└── tests/ # Тесты
Пример модификации config.m4:
dnl Указываем, что расширение не зависит от внешних библиотек
PHP_ARG_ENABLE(my_extension, whether to enable My Extension support,
[ --enable-my-extension Enable My Extension support])
if test "$PHP_MY_EXTENSION" != "no"; then
dnl Указываем, что расширение должно быть скомпилировано
PHP_NEW_EXTENSION(my_extension, my_extension.c, $ext_shared)
fi
Модифицируем my_extension.c
:
// Объявление функции
PHP_FUNCTION(my_extension_hello)
{
char *name = NULL;
size_t name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
RETURN_NULL();
}
php_printf("Hello, %s!\n", name);
RETURN_TRUE;
}
// Регистрация функции
static const zend_function_entry my_extension_functions[] = {
PHP_FE(my_extension_hello, NULL)
PHP_FE_END
};
zend_class_entry *my_extension_ce;
PHP_METHOD(MyExtensionClass, __construct)
{
zval *name;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &name) == FAILURE) {
RETURN_NULL();
}
zend_update_property(Z_OBJCE_P(getThis()), Z_OBJ_P(getThis()), "name", sizeof("name")-1, name);
}
// Регистрация методов класса
static const zend_function_entry my_extension_class_methods[] = {
PHP_ME(MyExtensionClass, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_FE_END
};
// В функции PHP_MINIT_FUNCTION
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "MyExtensionClass", my_extension_class_methods);
my_extension_ce = zend_register_internal_class(&ce);
phpize
./configure
make
sudo make install
Добавляем расширение в php.ini:
extension=my_extension.so
Пример PHP-кода для тестирования:
<?php
// Тестирование функции
my_extension_hello("World");
// Тестирование класса
$obj = new MyExtensionClass("Test");
?>
PHP_FUNCTION(my_extension_create_array)
{
array_init(return_value);
add_assoc_string(return_value, "key", "value");
add_index_long(return_value, 0, 42);
}
// Реализация интерфейса Iterator
zend_class_implements(my_extension_ce, 1, zend_ce_iterator);
Особенности для PHP 8:
gdb php
(gdb) run test_script.php
php_error_docref(NULL, E_NOTICE, "Debug message: %s", "value");
создание PHP-расширений требует глубокого понимания C и внутреннего устройства PHP, но открывает возможности для существенной оптимизации критического кода. Начинайте с простых функций, постепенно переходя к сложным структурам данных и интеграциям с системными библиотеками.