Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Extension API

Nishant Gupta edited this pageMay 21, 2016 ·20 revisions

HHVM provides a set of APIs for adding built-in functionality to the runtime either by way of pure PHP code, or a combination of PHP and C++ (HNI), or by C++ code and a JSON IDL file.

The IDL method for providing extensions is deprecated. The new HNI method should be used instead.

PHP-only extensions

For the simplest implementations, you can just write pure PHP code which will be built into your HHVM binary (as a block calledSystemLib) and loaded persistently for all requests. One example of this is theRedis extension which is written entirely in PHP, primarily inhphp/system/php/redis/Redis.php. As you can see, this looks just like any other script you'd write as part of an application, but because it is part ofSystemLib, it is loaded and available for every request.

Think of it like an auto_prepend_file, but handled in a persistent manner, so that the script isn't being reloaded each time.

To add your own function or class toSystemLib, place the implementation underhphp/system/php, and reference it fromhphp/system/php.txt. From here, the next time you rerun cmake and compile HHVM, it will be included in the binary as part of the runtime.

PHP and C++ extensions

Sometimes PHP just isn't enough and you need to duck into C++, perhaps to call a library function. For this, HHVM provides HNI (HHVM-Native Interface). An example of HNI can be seen inhphp/runtime/ext/fileinfo/ which makes up the fileinfo extension. Right away, you'll notice functions in ext_fileinfo.php with no implementation body, prefixed by<<__Native>>.

<<__Native>>functionfinfo_buffer(resource$finfo,                      ?string$string =NULL,                      int$options =FILEINFO_NONE,                      ?resource$context =NULL): string;

These are HNI stubs. The<<__Native>> attribute tells the compiler that rather than looking for a block of PHP code to be compiled, it should look for a symbol being exported by the C++ runtime named "finfo_buffer". Inside ext_fileinfo.cpp, we see the function being registered withinmoduleInit() asHHVM_FE(finfo_buffer);. We also see the mini-systemlib being loaded withloadSystemlib();.

staticclassfileinfoExtension :publicExtension {public:fileinfoExtension() : Extension("fileinfo") {}voidmoduleInit()override {/* etc...*/HHVM_FE(finfo_buffer);/* etc...*/loadSystemlib();  }} s_finfo_extension;

This, in turn, points at the actual implementation further up in the file:

static StringHHVM_FUNCTION(finfo_buffer,const Resource& finfo,const Variant& string,int64_t options,const Variant& context) {

As you can see, the parameter and return types have a 1:1 mapping between the PHP and C++ implementations. It is IMPORTANT that your internal types match your external types exactly. Failure will lead to undefined behavior (most likely a crash). See the table below for the types supported by HNI:

PHP TypeC++ Parameter TypeC++ Return TypeComment
voidN/AvoidReturn type for constructors only
boolboolboolBoolean (true/false)
intint64_tint64_t64-bit signed integer
floatdoubledoubleDouble precision floating point
stringconst String&StringHHVM String, similar to std::string
arrayconst Array&ArrayHHVM Array, similar to std::map/std::vector
resourceconst Resource&ResourceResource data type (e.g. file stream, db handle, etc...)
objectconst Object&ObjectObject data type
mixedconst Variant&VariantAble to represent any data type

In addition, a specific class type may be used (like a normal type hint), andObject arg/return types will apply as expected. Nullable (?type) and Soft (@type) typehints may be used, however they will fall back toVariant representation in the implementation's signature.

To pass an arg by reference, declare it in the PHP file asmixed type with an ampersand as usual (e.g.mixed &$foo) and useVRefParam as the internal type.

Dynamically Loadable Objects

In addition to built-in extensions, third-party developers may create an externally buildable DSO as is demonstrated by thehhvm/example extension. Here, you'll find a standalone mini-systemlib calledexample.php which performs the same introduction-to-the-compiler job as we saw in hash.php above. The matching implementations can, as expected, be found inexample.cpp. The magic comes fromconfig.cmake which instructs the build system on which files to build for which purpose. Please note thatHHVM_DEFINE_EXTENSION isonly for use in builtin extensions. It will not work for a DSO.

HHVM_EXTENSION(example example.cpp)HHVM_SYSTEMLIB(example example.php)

First, we define the extension binary we're building withHHVM_EXTENSION(${extension_name} ${filestobuild}). In this example we're only building one source file, but we could list any number of source files here.

Next, we select the PHP implementation to embed in this DSO as a mini-systemlib. Unlike the CPP sources, only one file may be embedded as a systemlib. If you want to split your project up into multiple systemlib sources, you'll need to compost them before compilation yourself.

Since this file is CMake, we can also link in other libraries with normal CMake commands such as the following:

find_package(LibFoo REQUIRED)include_directories(${LIBFOO_INCLUDE_DIR})HHVM_EXTENSION(foo foo1.cpp foo2.cpp foo3.c)target_link_libraries(foo${LIBFOO_LIBRARIES})HHVM_SYSTEMLIB(foo foo.php)

To build an HHVM extension, you'll follow a similar process to PHP extensions:

example$ hphpize** hphpize complete, now run`cmake.&& make` to buildexample$ cmake.[ lots of output ]example$ make[ lots more output ]** Built target example

The extension may now be loaded by adding the following to your .ini file:

hhvm.dynamic_extension_path = /path/to/foohhvm.dynamic_extensions[foo] = foo.so

NOTE: when trying to load Zend extension, [hhvm.enable_zend_compat](INI Settings) ini setting needs to be enabled.

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp