Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning "Native" PHP Objects from an Extension

I'm dabbling with creating a PHP extension for a personal project. Beyond what's linked in the above article I have no knowledge of the zend_engine, and my C skills are 10 years out of date, and were only ever academic. All of which is to say "If it seems like I'm asking a dumb question, I probably am".

Is it possible to call functions from other PHP extensions in my own extension, or is each PHP extension considered an island, with no insight into other parts of the system? If this is possible, is it common practice, or a Bad Idea™?

That is, I know I can return a string with something like this.

PHP_FUNCTION(hello_world)
{
    char *str;
    str = estrdup("Hello World");
    RETURN_STRING(str, 0);
}

I'd like to be able to return, say, a SimpleXML element, or a DomDocument element. Googling has proven difficult, as there's not a ton out there about extension development, and there IS a ton out there about standard PHP usage.

like image 347
Alan Storm Avatar asked Mar 19 '12 16:03

Alan Storm


1 Answers

Yes, extensions can in fact depend on others. They can:

  • Use resources that other extensions register globally, such as class types or PHP functions (that is, they don't have less access than user-land scripts, which can obviously use those resources). See zend_call_function and zend_lookup_class_ex.
  • Use any exported symbols and structures that are declared in the file php_extensionname.h (these headers are the only ones that are considered to a export a native API to other extensions). However, some extensions may in fact NOT export some symbols declared in those header files, you must look for symbols declared with PHPAPI. Note that some extensions cannot be deactivated and you can rely on them being present (for instance, as of 5.3/5.4, standard, SPL, reflection, date, pcre, ereg).
  • If both your extension and target extension are built statically, you have of course more latitude on the symbols you can use, but it's not a good practice to use non-exported symbols.

I'd like to be able to return, say, a SimpleXML element, or a DomDocument element.

If you need to explicitly instantiate a SimpleXMLElement or a DOMDocument, you can do so with object_init_ex. Extensions usually export the zend_class_entry * that have to pass that macro, but if not you can always use zend_lookup_class_ex. This does NOT call the constructor, so you still must do so manually if you need to.

Some extensions may provide a native interface to instantiate and initialize an object, but in general extensions are not prepared to have other extensions instantiate their types.

Of course, you can also, like a script, call PHP functions and methods that return any of those types. You'll get a zval * that you can in turn return from your function.

As to how to declare the dependencies, the extension descriptor has an entry for this. This will ensure your extension is loaded after the ones you declare you depend on. For declaring the dependency at compile time see PHP_ADD_EXTENSION_DEP.

like image 87
Artefacto Avatar answered Oct 22 '22 03:10

Artefacto