#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef PHP_WIN32
#include <iostream>
#include <math.h>
#endif
extern "C" {
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
}
#include "php_cppext.h"
#include "class.h"
/* Note 1 -- here's the zend_class_entry. You'll also
need a list entry for the resources used to store the
actual C++ objects... */
static zend_class_entry myphpclass_entry;
static int le_myphpclass;
/* Note 2 -- all of the methods go into this
function_entry. Below are the actual methods that
map onto MyPHPClass. */
function_entry cppext_functions[] = {
PHP_FE(myphpclass, NULL)
PHP_FE(myphpclass_getstring, NULL)
PHP_FE(myphpclass_setstring, NULL)
{NULL, NULL, NULL}
};
static function_entry myphpclass_methods[] = {
{"getstring", PHP_FN(myphpclass_getstring), NULL},
{"setstring", PHP_FN(myphpclass_setstring), NULL},
{NULL, NULL, NULL}
};
/* {{{ cppext_module_entry
*/
zend_module_entry cppext_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"cppext",
cppext_functions,
PHP_MINIT(cppext),
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
"0.1",
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_CPPEXT
BEGIN_EXTERN_C()
ZEND_GET_MODULE(cppext)
END_EXTERN_C()
#endif
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(cppext)
{
/* Note 3 -- here we register the destructor for the myphpclass PHP objects,
which deletes the actual C++ objects. Below that, we initialize the
class entry for myphpclass. */
le_myphpclass = zend_register_list_destructors_ex(destroy_myphpclass, NULL, "myphpclass-obj", module_number);
INIT_CLASS_ENTRY(myphpclass_entry, "myphpclass", myphpclass_methods);
zend_register_internal_class(&myphpclass_entry TSRMLS_CC);
return SUCCESS;
}
/* }}} */
/* {{{ proto myphpclass object myphpclass()
Returns a new myphpclass object. This is basically the constructor. */
PHP_FUNCTION(myphpclass)
{
/* Note 4 -- here's the constructor. First, initalize return_value as an
object, then make a handle to the C++ object. Register the handle as a resource
and store the resource within the PHP object so we can get to it in the method
calls. */
MyPHPClass *obj;
zval *handle;
if (ZEND_NUM_ARGS() != 0) {
WRONG_PARAM_COUNT;
}
obj = new MyPHPClass;
object_init_ex(return_value, &myphpclass_entry);
MAKE_STD_ZVAL(handle);
ZEND_REGISTER_RESOURCE(handle, obj, le_myphpclass);
zend_hash_update(Z_OBJPROP_P(return_value), "handle", sizeof("handle"), &handle, sizeof(zval *), NULL);
}
/* }}} */
/* Note 5 -- this macro gets the resource handle for the C++ object so we can
use the C++ object in our methods mappings below. */
#define CPP_GET_THIS() \
id = getThis(); \
if (!id) { \
php_error(E_ERROR, "this isn't an object?! %s()", get_active_function_name(TSRMLS_C)); \
} \
if (zend_hash_find(Z_OBJPROP_P(id), "handle", sizeof("handle"), (void **) &handle) == FAILURE) { \
php_error(E_ERROR, "underlying object missing, can't find 'this' in %s()", get_active_function_name(TSRMLS_C)); \
} \
obj = (MyPHPClass *) zend_list_find(Z_LVAL_PP(handle), &type); \
if (!obj || type != le_myphpclass) { \
php_error(E_ERROR, "underlying object is of wrong type in %s()", get_active_function_name(TSRMLS_C)); \
}
/* {{{ proto string myphpclass->getstring()
Passthru to MyPHPClass::getString(). */
PHP_FUNCTION(myphpclass_getstring)
{
MyPHPClass *obj;
zval *id, **handle;
int type;
CPP_GET_THIS();
RETURN_STRINGL((char*) obj->getString().c_str(), obj->getString().length(), 1);
}
/* }}} */
/* {{{ proto bool myphpclass->setstring(string)
Passthru to MyPHPClass::setString(string). */
PHP_FUNCTION(myphpclass_setstring)
{
MyPHPClass *obj;
zval *id, **handle;
int type, len;
char *str;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
RETURN_FALSE;
}
else {
CPP_GET_THIS();
obj->setString(str);
RETURN_TRUE;
}
}
/* }}} */
/* {{{ destructor for myphpclass objects */
static void destroy_myphpclass(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
delete (MyPHPClass*) rsrc->ptr;
}
/* }}} */
|