今日、私はほぼ 1 日かけて PHP の関連する C++ 拡張機能を勉強しましたが、最初にそれらに触れたとき、多くの点で不慣れで、多くの落とし穴に遭遇しました。ここでは、主に次の記事を参照します。 //devzone .zend.com/1435/wrapping-c-classes-in-a-php-extension/:
これで、いくつかのメンバー関数を含む Car クラスが定義されました。拡張機能全体に含まれるファイルは次のとおりです。
1 #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(); }
<pre class="code">/ 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.