时间:2021-07-01 10:21:17 帮助过:3人阅读
1 PHP_ARG_ENABLE(vehicles, 2 [Whether to enable the "vehicles" extension], 3 [ --enable-vehicles Enable "vehicles" extension support]) 4 5 if test $PHP_VEHICLES != "no"; then 6 PHP_REQUIRE_CXX() 7 PHP_SUBST(VEHICLES_SHARED_LIBADD) 8 PHP_ADD_LIBRARY(stdc++, 1, VEHICLES_SHARED_LIBADD) 9 PHP_NEW_EXTENSION(vehicles, vehicles.cc car.cc, $ext_shared) 10 fi
#ifndef VEHICLES_CAR_H
  2 #define VEHICLES_CAR_H
  3 
  4 // A very simple car class
  5 class Car {
  6 public:
  7     Car(int maxGear);
  8     void shift(int gear);
  9     void accelerate();
10     void brake();
11     int getCurrentSpeed();
12     int getCurrentGear();
13 private:
14     int maxGear;
15     int currentGear;
16     int speed;
17 };
18 
19 #endif /* VEHICLES_CAR_H */ 
这个跟c++的头文件声明是完全一样的.
 
类的源文件car.cc
源文件也是,属于C++的类定义
  2 #include "car.h"
  3 Car::Car(int maxGear) {
  4     this->maxGear = maxGear;
  5     this->currentGear = 1;
  6     this->speed = 0;
  7 }
  9 void Car::shift(int gear) {
10     if (gear < 1 || gear > maxGear) {
11         return;
12     }
13     currentGear = gear;
14 }
16 void Car::accelerate() {
17     speed += (5 * this->getCurrentGear());
18 }
20 void Car::brake() {
21     speed -= (5 * this->getCurrentGear());
22 }
24 int Car::getCurrentSpeed() {
25     return speed;
26 }1 #ifndef PHP_VEHICLES_H
  2 #define PHP_VEHICLES_H
  4 #define PHP_VEHICLES_EXTNAME  "vehicles"
  5 #define PHP_VEHICLES_EXTVER   "0.1"
  7 #ifdef HAVE_CONFIG_H
  8 #include "config.h"
  9 #endif
10 
11 extern "C" {
12 #include "php.h"
13 }
14 
15 extern zend_module_entry vehicles_module_entry;
16 #define phpext_vehicles_ptr &vehicles_module_entry;
17 
18 #endif /* PHP_VEHICLES_H */
 
首先用宏判断这个头文件是不是已经包含了.然后在第四行给这个扩展一个别名.第五行给定版本号.
注意在11到13行用extern "C"包含了起来,这是因为php是用c写的,所以在开发c++扩展的时候一定要声明一下.
第15行声明了整个扩展模块的入口,在这个入口函数中会定义诸如MINIT\RINIT这种startup函数 和 MSHUTDOWN RSHUTDOWN这种shutdown函数.
 
php扩展的源文件vehicles.cc:
这个文件里面的内容相当多,因为它承载了如何把我们想要的c++的类与php的内核联系起来的任务.同时在这个文件中还需要把类中的成员函数进行相应的mapping,以方便php可以直接调用.这些功能会在下面的源码中一一加以说明:
在第一阶段的代码里,先不涉及类相关的部分,而是循序渐进,这里的代码先给出常规php扩展源码中需要进行的一些操作:
1 #include "php_vehicles.h"
2 PHP_MINIT_FUNCTION(vehicles)
3 {
4    return SUCCESS;
5 }
6 zend_module_entry vehicles_module_entry = {
7 #if ZEND_MODULE_API_NO >= 20010901
8    STANDARD_MODULE_HEADER,
9 #endif
10    PHP_VEHICLES_EXTNAME,
11    NULL,                  /* Functions */
12    PHP_MINIT(vehicles),
13    NULL,                  /* MSHUTDOWN */
14    NULL,                  /* RINIT */
15    NULL,                  /* RSHUTDOWN */
16    NULL,                  /* MINFO */
17 #if ZEND_MODULE_API_NO >= 20010901
18    PHP_VEHICLES_EXTVER,
19 #endif
20    STANDARD_MODULE_PROPERTIES
21 };
22 #ifdef COMPILE_DL_VEHICLES
23 extern "C" {
24 ZEND_GET_MODULE(vehicles)
25}
26 #endif1  #include "php_vehicles.h"
2  zend_class_entry *car_ce;
3  PHP_METHOD(Car, __construct){}
5  PHP_METHOD(Car, shift) {}
7  PHP_METHOD(Car, accelerate) {}
9  PHP_METHOD(Car, brake) {}
11  PHP_METHOD(Car, getCurrentSpeed){}
13  PHP_METHOD(Car, getCurrentGear){}
15  zend_function_entry car_methods[] = {
16    PHP_ME(Car,  __construct,     NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
17    PHP_ME(Car,  shift,           NULL, ZEND_ACC_PUBLIC)
18    PHP_ME(Car,  accelerate,      NULL, ZEND_ACC_PUBLIC)
19    PHP_ME(Car,  brake,           NULL, ZEND_ACC_PUBLIC)
20    PHP_ME(Car,  getCurrentSpeed, NULL, ZEND_ACC_PUBLIC)
21    PHP_ME(Car,  getCurrentGear,  NULL, ZEND_ACC_PUBLIC)
22    {NULL, NULL, NULL}
23  };
24  PHP_MINIT_FUNCTION(vehicles)
25  {
26    zend_class_entry ce;
27    INIT_CLASS_ENTRY(ce, "Car", car_methods);
28    car_ce = zend_register_internal_class(&ce TSRMLS_CC);
29    return SUCCESS;
30  }
31  zend_module_entry vehicles_module_entry = {
32  #if ZEND_MODULE_API_NO >= 20010901
33     STANDARD_MODULE_HEADER,
34  #endif
35    PHP_VEHICLES_EXTNAME,
36    NULL,        /* Functions */
37    PHP_MINIT(vehicles),        /* MINIT */
38    NULL,        /* MSHUTDOWN */
39    NULL,        /* RINIT */
40    NULL,        /* RSHUTDOWN */
41    NULL,        /* MINFO */
42  #if ZEND_MODULE_API_NO >= 20010901
43    PHP_VEHICLES_EXTVER,
44  #endif
45    STANDARD_MODULE_PROPERTIES
46 };
47  #ifdef COMPILE_DL_VEHICLES
48  extern "C" {
49  ZEND_GET_MODULE(vehicles)
50  }
51  #endif1  #include "car.h"
2  zend_object_handlers car_object_handlers;
3  struct car_object {
4     zend_object std;
5     Car *car;
6  };1  void car_free_storage(void *object TSRMLS_DC)
2  {
3    car_object *obj = (car_object *)object;
4    delete obj->car; 
5    zend_hash_destroy(obj->std.properties);
6    FREE_HASHTABLE(obj->std.properties);
7    efree(obj);
8  }
9  zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
10  {
11    zval *tmp;
12    zend_object_value retval;
13    car_object *obj = (car_object *)emalloc(sizeof(car_object));
14    memset(obj, 0, sizeof(car_object));
15    obj->std.ce = type;
16    ALLOC_HASHTABLE(obj->std.properties);
17    zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
18    zend_hash_copy(obj->std.properties, &type->default_properties,
19        (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
20    retval.handle = zend_objects_store_put(obj, NULL,
21        car_free_storage, NULL TSRMLS_CC);
22    retval.handlers = &car_object_handlers;
23    return retval;
24 }25 PHP_MINIT_FUNCTION(vehicles)
26 {
27    zend_class_entry ce;
28    INIT_CLASS_ENTRY(ce, "Car", car_methods);
29    car_ce = zend_register_internal_class(&ce TSRMLS_CC);
30    car_ce->create_object = car_create_handler;
31    memcpy(&car_object_handlers,
32        zend_get_std_object_handlers(), sizeof(zend_object_handlers));
33    car_object_handlers.clone_obj = NULL;
34    return SUCCESS;
35}
 1  PHP_METHOD(Car, __construct)
2  {
3     long maxGear;
4    Car *car = NULL;
5    zval *object = getThis();
6    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &maxGear) == FAILURE) {
7        RETURN_NULL();
8    }
9    car = new Car(maxGear);
10    car_object *obj = (car_object *)zend_object_store_get_object(object TSRMLS_CC);
11    obj->car = car;
12  }PHP_METHOD(accelerate)
{
    Car *car;
    car_object *obj = (car_object *)zend_object_store_get_object(
        getThis() TSRMLS_CC);
    car = obj->car;
    if (car != NULL) {
        car->accelerate();
    }
}
PHP_METHOD(getCurrentSpeed)
{
    Car *car;
    car_object *obj = (car_object *)zend_object_store_get_object(
        getThis() TSRMLS_CC);
    car = obj->car;
    if (car != NULL) {
        RETURN_LONG(car->getCurrentSpeed());
    }
    RETURN_NULL();
}如果说输出跟标识的一致的话,那么整个过程就成功了,恭喜!/ create a 5 gear car $car = new Car(5); print $car->getCurrentSpeed(); // prints '0' $car->accelerate(); print $car->getCurrentSpeed(); // prints '5' If you can run this script, congratulations, you’ve just created a PHP extension that wraps a C++ class.
http://www.bkjia.com/PHPjc/621614.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/621614.htmlTechArticle今天花了几乎一天的时间研究php的相关c扩展,第一次接触的时候很多地方不太熟悉,也碰到了不少坑,这里把整个过程叙述如下,参考的文...