我正在编写一个 PHP 扩展。在它里面我有我自己的函数,它只写一个传递给这个函数的字符串参数。我将 Apache 2.4 和 PHP-FPM 与 PHP 5.4.8 一起使用。在 PHP-FPM 配置中,我只有一个进程来处理 PHP 请求。
我有一个只有这个功能的简单示例。对于第一个请求,一切似乎都很好,但第二个请求返回“调用未定义函数”致命错误。
是否有一些特殊的方法可以为 PHP-FPM 编写扩展,或者它可能是 PHP 中的一个错误?
编辑:
代码 - config.m4:
dnl $Id$
dnl config.m4 for extension phpExtension
PHP_ARG_ENABLE(phpExtension, whether to enable phpExtension support,
[ --enable-phpextension Enable phpExtension support])
if test "$PHP_PHPEXTENSION" != "no"; then
PHP_REQUIRE_CXX()
PHP_NEW_EXTENSION(phpExtension, phpExtension.cpp, $ext_shared)
PHP_SUBST(PHPEXTENSION_SHARED_LIBADD)
PHP_ADD_LIBRARY(stdc++, 1, PHPEXTENSION_SHARED_LIBADD)
fi
phpExtension.h:
#ifndef PHP_PHPEXTENSION_H
#define PHP_PHPEXTENSION_H
extern zend_module_entry phpExtension_module_entry;
#define phpext_phpExtension_ptr &phpExtension_module_entry
#ifdef PHP_WIN32
# define PHP_PHPEXTENSION_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_PHPEXTENSION_API __attribute__ ((visibility("default")))
#else
# define PHP_PHPEXTENSION_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
PHP_MINIT_FUNCTION(phpExtension);
PHP_MSHUTDOWN_FUNCTION(phpExtension);
PHP_RINIT_FUNCTION(phpExtension);
PHP_RSHUTDOWN_FUNCTION(phpExtension);
PHP_MINFO_FUNCTION(phpExtension);
PHP_FUNCTION(phpExtensionTest);
#ifdef ZTS
#define phpExtension_G(v) TSRMG(phpExtension_globals_id, zend_phpExtension_globals *, v)
#else
#define phpExtension_G(v) (phpExtension_globals.v)
#endif
ZEND_BEGIN_MODULE_GLOBALS(phpExtension)
ZEND_END_MODULE_GLOBALS(phpExtension)
static PHP_GINIT_FUNCTION(phpExtension);
static PHP_GSHUTDOWN_FUNCTION(phpExtension);
static int php_phpExtension_post_deactivate();
#endif /* PHP_PHPEXTENSION_H */
phpExtension.cpp:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <iostream>
#include <set>
#include <utility>
#include <string>
extern "C"
{
#include <ctype.h> //tolower
#include <stdio.h>
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "zend_vm_opcodes.h"
#include "zend_compile.h"
#include "zend_hash.h"
#include "zend_operators.h"
#include "zend_exceptions.h"
#include "php_phpExtension.h"
#include "zend_API.h"
#include "SAPI.h"
#include "zend_llist.h"
#include "zend.h"
#include "php_syslog.h"
#include <syslog.h>
}
using namespace std;
ZEND_DLEXPORT zend_function_entry phpExtension_functions[] =
{
PHP_FE(phpExtensionTest, NULL)
PHP_FE_END /* Must be the last line in phpExtension_functions[] */
};
ZEND_DECLARE_MODULE_GLOBALS(phpExtension)
zend_module_entry phpExtension_module_entry =
{
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"phpExtension",
phpExtension_functions,
PHP_MINIT(phpExtension),
PHP_MSHUTDOWN(phpExtension),
PHP_RINIT(phpExtension),
PHP_RSHUTDOWN(phpExtension),
PHP_MINFO(phpExtension),
#if ZEND_MODULE_API_NO >= 20010901
"0.1", /* TODO Replace with version number for your extension */
#endif
PHP_MODULE_GLOBALS(phpExtension),
PHP_GINIT(phpExtension),
PHP_GSHUTDOWN(phpExtension),
php_phpExtension_post_deactivate,
STANDARD_MODULE_PROPERTIES_EX
};
extern "C"
{
#ifdef COMPILE_DL_PHPEXTENSION
ZEND_GET_MODULE(phpExtension)
#endif
}
/**
* Initializes global parameters
*/
static PHP_GINIT_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension ginit\n");
fflush(stderr);
}
static PHP_GSHUTDOWN_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension gshutdown\n");
fflush(stderr);
}
static int php_phpExtension_post_deactivate()
{
fprintf(stderr, "phpExtension php_phpExtension_post_deactivate\n");
fflush(stderr);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension mshutdown\n");
fflush(stderr);
return SUCCESS;
}
PHP_RINIT_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension rinit\n");
fflush(stderr);
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension rshutdown\n");
fflush(stderr);
return SUCCESS;
}
PHP_MINFO_FUNCTION(phpExtension)
{
php_info_print_table_start();
php_info_print_table_header(2, "phpExtension support", "enabled");
php_info_print_table_end();
}
PHP_FUNCTION(phpExtensionTest)
{
int len;
char *str;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE)
{
RETURN_NULL();
}
php_printf("passed string: %s\n", str);
RETURN_NULL();
}
PHP_MINIT_FUNCTION(phpExtension)
{
fprintf(stderr, "phpExtension SAPI: %s %s\n", sapi_module.name, sapi_module.pretty_name);
fflush(stderr);
return SUCCESS;
}
和 script.php:
<?php
phpExtensionTest("Test");