All Projects → llgoer → php-ffi-rust

llgoer / php-ffi-rust

Licence: other
PHP7.4 + Rust

Programming Languages

c
50402 projects - #5 most used programming language
PHP
23972 projects - #3 most used programming language
rust
11053 projects
python
139335 projects - #7 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to php-ffi-rust

php-fuse
PHP FFI bindings for libfuse
Stars: ✭ 53 (+89.29%)
Mutual labels:  ffi, php-ffi
php-rdkafka-ffi
PHP Kafka client - binding librdkafka via FFI
Stars: ✭ 49 (+75%)
Mutual labels:  ffi, php-ffi
ext-psi
PHP System Interface (aka FFI)
Stars: ✭ 24 (-14.29%)
Mutual labels:  ffi, php-ffi
cxx-cmake-example
An example repo to setup cxx (Rust FFI library) with the CMake build system.
Stars: ✭ 64 (+128.57%)
Mutual labels:  ffi
pedax
Reversi Board with edax, which is the strongest reversi engine.
Stars: ✭ 18 (-35.71%)
Mutual labels:  ffi
yajl-ffi
Ruby FFI bindings to the native YAJL streaming JSON parser.
Stars: ✭ 15 (-46.43%)
Mutual labels:  ffi
ffi-sdl
PHP FFI SDL bindings
Stars: ✭ 23 (-17.86%)
Mutual labels:  ffi
Rustler
Safe Rust bridge for creating Erlang NIF functions
Stars: ✭ 3,052 (+10800%)
Mutual labels:  ffi
r6rs-pffi
Portable Foreign Function Interface (FFI) for R6RS
Stars: ✭ 40 (+42.86%)
Mutual labels:  ffi
DotNET.jl
Julia ❤️ .NET
Stars: ✭ 75 (+167.86%)
Mutual labels:  ffi
rsmpeg
A Rust crate that exposes FFmpeg's power as much as possible.
Stars: ✭ 390 (+1292.86%)
Mutual labels:  ffi
allo-isolate
Run Multithreaded Rust along with Dart VM (in isolate) 🌀
Stars: ✭ 93 (+232.14%)
Mutual labels:  ffi
sqlite3
The fastest and correct module for SQLite3 in Deno.
Stars: ✭ 143 (+410.71%)
Mutual labels:  ffi
elixir-ffi
Foreign Function Interface (FFI) for Elixir
Stars: ✭ 52 (+85.71%)
Mutual labels:  ffi
JitFFI
A fast and customizable JIT compiler for FFI (Foreign-Function Interface).
Stars: ✭ 45 (+60.71%)
Mutual labels:  ffi
Curryrs
Bridge the gap between Haskell and Rust
Stars: ✭ 252 (+800%)
Mutual labels:  ffi
rdp
A library providing FFI access to fast Ramer–Douglas–Peucker and Visvalingam-Whyatt line simplification algorithms
Stars: ✭ 20 (-28.57%)
Mutual labels:  ffi
tflite native
A Dart interface to TensorFlow Lite (tflite) through dart:ffi
Stars: ✭ 127 (+353.57%)
Mutual labels:  ffi
efi
Ergonomic Rust framework for writing UEFI applications.
Stars: ✭ 44 (+57.14%)
Mutual labels:  ffi
darknet
php ffi darknet
Stars: ✭ 21 (-25%)
Mutual labels:  php-ffi

php-ffi-rust

本项目目标就是采用Rust编写扩展库,提供给PHP7.4的FFI扩展,看看是否能够抢救一下PHP。

拓展

创建一个PHP扩展调用Rust动态库

测试环境

macOS:10.13.6

PHP:7.4.0beta1

Rust:1.36.0

为macOS编译PHP

由于MacOS下没有找到合适的PHP7.4版本,所以只能自己动手编译。

下载

从PHP的Github Release页面下载PHP7.4.0beta1版本。

编译PHP

确保系统安装autoconf,如果没有安装,执行brew install autoconf进行安装。

确保系统安装bison,re2c,libffi

$ ./buildconf --force
$ ./configure --prefix=/Users/llgoer/php-ffi-rust/dist --with-ffi 
$ make && make install

这里注意,如果编译没有找到libffi,可以采用

FFI_CFLAGS=/xxx/libffi-3.2.1/include FFI_LIBS=/xxx/libffi/3.2.1/lib ./configure ...

指定

运行PHP7.4

进入dist目录,我们可以看到我们已经编译好的PHP7.4。

$ ./php -version
PHP 7.4.0beta1 (cli) (built: Aug  2 2019 22:12:05) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies

$ ./php -m
[PHP Modules]
Core
ctype
date
dom
FFI
fileinfo
filter
hash
iconv
json
libxml
pcre
PDO
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter

[Zend Modules]

如果存在FFI扩展则表示编译正常。

安装Rust环境

这里就不多说了,可以去Rust官方网站看看。

Rust编写一个动态连接库

执行

$ cargo new r2p-fib --lib

创建一个rust库,修改Cargo.toml,配置项目生成动态链接库

[package]
name = "r2p-fib"
version = "0.1.0"
authors = ["llgoer <[email protected]>"]
edition = "2018"

[dependencies]
name = "r2pfib"
crate-type = ["dylib"]

在lib.rs中创建一个导出的fib函数:

#[no_mangle]
pub extern fn fib(n: i32) -> i32 {
  return match n {
    1 | 2 => 1,
    n => fib(n - 1) + fib(n - 2)
  }
}

执行cargo build以及cargo build --release,生成对应的扩展库。

编写PHP代码

编写test-ffi.php

<?php
// 一个PHP的fib函数
function fib($n) {
	if ($n < 0) {
		return NULL;
	} elseif ($n === 0) {
		return 0;
	} elseif ($n === 1 || $n === 2) {
		return 1;
	} else {
		return fib($n-1) + fib($n-2);
	}	 
}

// 这里测试PHP下的Fib函数
$time_start = microtime(true);
for ($i=0; $i < 100000; $i++) { 
	fib(12);
}
echo '[PHP]fib执行时间:' . (microtime(true) - $time_start).PHP_EOL;


// 下面则是测试Rust的扩展,我们采用debug、release两种模式
$libExtension = (PHP_OS_FAMILY == "Darwin" ? 'dylib' : 'so');

// debug模式
$ffiDebug = FFI::cdef(
    "int32_t fib(int32_t n);",
    "r2p-fib/target/debug/libr2pfib.$libExtension");

$time_start = microtime(true);
for ($i=0; $i < 1000000; $i++) { 
	$ffiDebug->fib(12);
}

echo '[Rust]Debug执行时间:' . (microtime(true) - $time_start).PHP_EOL;

// release模式
$ffiRelease = FFI::cdef(
    "int32_t fib(int32_t n);",
    "r2p-fib/target/release/libr2pfib.$libExtension");

$time_start = microtime(true);
for ($i=0; $i < 1000000; $i++) { 
	$ffiRelease->fib(12);
}

echo '[Rust]Release执行时间:' . (microtime(true) - $time_start).PHP_EOL;
?>

查看测试结果

执行make test-php查看结果,看看惊不惊喜,意不意外。

[PHP]fib执行时间:3.624843120575
[Rust]Debug执行时间:2.0988941192627
[Rust]Release执行时间:0.56653189659119

字符串测试

我们编写了一个生成字符串的调用测试,详细可以参考test-ffi2.php

这个例子告诉我们,这里频繁调用字符串解析是比较消耗性能的。

[Rust]debug执行时间:7.8468458652496
string(52) "💣na na na na na na na na na na na na Batman! 💣"
[Rust]release执行时间:1.4546401500702
string(52) "💣na na na na na na na na na na na na Batman! 💣"
[PHP]执行时间:0.23888492584229
string(52) "💣na na na na na na na na na na na na Batman! 💣"

总结

目前PHP同Rust结合有几种方式:1.PHP的FFI调用Rust导出的库;2.编写PHP扩展调用Rust动态库;3.直接采用Rust编写PHP扩展库;

第一种目前并不成熟,而且受限于PHP7.4+,所以不是很推荐,仅限于兴趣研究,另外FFI性能损耗也是比较大,频繁调用处理非常不推荐。

第二种比较实用,如果想为PHP添加一些额外扩展也是非常推荐这种方式,将Rust开发的库按照格式导出再交给PHP调用处理。

第三种基本上需要将PHP的C API导出为Rust方法,然后直接在Rust中编写PHP的扩展,这种方式目前还没尝试。

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].