i am new to php extension development in windows and following this article series to learn it:- https://jojokahanding.wordpress.com/2014/05/26/writing-php-extensions-for-windowswriting-the-extension/
I've successfully built compile environment for extension development by following this article . It was building successfully. But when i wrote function in it to add two numeric values and tried to build it. It throws me this error at Line 11 in phpTestModule.php:-
'zif_test_addme': undeclared identifier
Line 11 code is :-
PHP_FE(test_addme,NULL)
Why am i getting this error?
I have googled and found this from php website and tried to replace PHP_FE by ZEND_FE and end it by ZEND_FE_END. But even that also didn't work and i end up getting same error. Plz help.
PS :- I am using Visual Studio 2017 and PHP 7.0.22 to build extension and my system is 64 bit.
Code snippets:-
phpTestModule.cpp
// phpTestModule.cpp : Defines the exported functions for the DLL
application.
//
#include "stdafx.h"
#define PHP_TEST_EXTNAME "test"
#define PHP_TEST_VERSION "1.0.30"
zend_function_entry test_functions[] = {
PHP_FE(test_addme,NULL)
{NULL,NULL,NULL}
};
zend_module_entry test_module_entry = {
#if ZEND_MODULE_API_NO>=20010901
STANDARD_MODULE_HEADER,
#endif
PHP_TEST_EXTNAME,
test_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO>=20010901
PHP_TEST_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE(test);
PHP_FUNCTION(test_addme)
{
long paramOne;
long paramTwo;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", ¶mOne, ¶mTwo) == FAILURE)
{
RETURN_FALSE;
}
RETURN_LONG(paramOne + paramTwo);
}
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#ifdef _DEBUG
#define ZEND_DEBUG 1
#else
#define ZEND_DEBUG 0
#endif
#define ZTS 1
#define ZEND_WIN32 1
#define PHP_WIN32 1
#include<math.h>
#include<wchar.h>
#include<io.h>
#include<php.h>
#pragma comment(lib,"php7ts.lib")
// TODO: reference additional headers your program requires here
You need to forward-declare the PHP function binding. You can do this either in the header as an external function or as a static function in the phpTestModule.cpp
compilation unit.
Make sure to use the PHP_FUNCTION
macro to do this just like you did for the definition.
Example
// Forward declare PHP function bindings:
static PHP_FUNCTION(test_addme);
// Define list of functions provided by the extension module:
zend_function_entry test_functions[] = {
PHP_FE(test_addme,NULL)
{NULL,NULL,NULL}
};
// PHP function binding definition:
PHP_FUNCTION(test_addme)
{
long paramOne;
long paramTwo;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", ¶mOne, ¶mTwo) == FAILURE)
{
RETURN_FALSE;
}
RETURN_LONG(paramOne + paramTwo);
}
Explanation
The PHP_FUNCTION
macro basically evaluates to a normal C function declaration/definition. It maps to something like void zif_test_addme(INTERNAL_FUNCTION_PARAMETERS)
where INTERNAL_FUNCTION_PARAMETERS
is a macro defining the actual arguments required by the function binding implementation (you don't actually have to worry about these). You can use this in both a declaration context or definition. Of course, a definition is also a declaration so you could have just moved the implementation of PHP_FUNCTION(test_addme)
before the zend_function_entry
declaration.