To write a PHP Class in C you need to deal with the zend_class_entry, a data structure that will contain your object methods, properties and so on.

To declare a class you have to declare it in your file and register it in the MINIT.

zend_class_entry *ce_Example;

zend_function_entry php_example_methods[] = {
    PHP_FE_END
};

PHP_MINIT_FUNCTION(example)  {
    zend_class_entry ce_example_local;
    INIT_CLASS_ENTRY(ce_example_local, "Example", php_example_methods);
    ce_Example = zend_register_internal_class(&ce_example_local TSRMLS_CC);
    return SUCCESS;
}

Now we have an empty Example() class with no methods or properties.

The next step is to complete our class with a method setName that update the name property

zend_class_entry *ce_Example;

PHP_METHOD(example, setName) {
   zval *obj;

    char *name;
    int name_len;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &obj, ce_Example, &name, &name_len) == FAILURE) {
        RETURN_NULL();
    }
    
    zend_update_property_string(cld2_detector_ce, obj, "name", sizeof("name") - 1, name TSRMLS_CC);

}


ZEND_BEGIN_ARG_INFO(arginfo_example_set_name, 0)
    ZEND_ARG_INFO(0, name)
ZEND_END_ARG_INFO()

zend_function_entry php_example_methods[] = {
    PHP_ME(example, setName, arginfo_example_set_name, ZEND_ACC_PUBLIC)
}

PHP_MINIT_FUNCTION(example)  {
    zend_class_entry ce_example_local;
    INIT_CLASS_ENTRY(ce_example_local, "Example", php_example_methods);
    ce_Example = zend_register_internal_class(&ce_example_local TSRMLS_CC);
    zend_declare_property_string(ce_Example, "name", sizeof("name") - 1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
    return SUCCESS;
}

As you can see we declared a setName method using PHP_METHOD and to connect the method to the class we added it to its zend_function_entry namely php_example_methods finally we added arguments informations with ZEND_BEGIN_ARG_INFO, in this specific case this statement declares that the setName method has only one argument named “name”. We also updated the MINIT function to declare the name property that the method setName uses.

To declare the name property we used zend_declare_property_string but there are also functions to declare all other available types. For reference you can browse the zend_API.h from the php-src repository from line 308 to line 315 (tag: php-5.6.2).

https://github.com/php/php-src/blob/f94c1df85fb004bb35091da5cebe730589a409b8/Zend/zend_API.h#L308...L315

Now after compiling and installing our extension we can use the just like any other:

<?php
$clazz = new Example();
$clazz->setName("Lorenzo");
echo $clazz->name;

As result of what you did you can issue a 

php -rc Example

That will return the reflection of your Class showing that it has one property, the name and one method setName that accept only one required parameter.

Class [ <internal:hello_world> class Example ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [1] {
    Property [ <default> public $name ]
  }

  - Methods [1] {
    Method [ <internal:hello_world> public method setName ] {

      - Parameters [1] {
        Parameter #0 [ <required> $name ]
      }
    }
  }
}

Comments

comments powered by Disqus

cloudparty

Follow Us