Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98212 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 17374 invoked from network); 5 Feb 2017 22:05:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Feb 2017 22:05:16 -0000 Authentication-Results: pb1.pair.com header.from=bowersbros@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=bowersbros@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.128.172 as permitted sender) X-PHP-List-Original-Sender: bowersbros@gmail.com X-Host-Fingerprint: 209.85.128.172 mail-wr0-f172.google.com Received: from [209.85.128.172] ([209.85.128.172:33345] helo=mail-wr0-f172.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0D/22-30708-991A7985 for ; Sun, 05 Feb 2017 17:05:14 -0500 Received: by mail-wr0-f172.google.com with SMTP id i10so14520583wrb.0 for ; Sun, 05 Feb 2017 14:05:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=Lkcgr6kvMByJr04YkQx+Ocnof4wSvPnlI3aepi8aH74=; b=DqKk5IT5pQ2uyEAPPM92aFFOvrAn4P6St6mp6E9PIiOAaACzBtmc2aTXh9eI/UyIoB cm+pDM/d6X1P5TNXfdF2fcVpnU2z+YcU7x2q66BNzhs/eTfA6WKADSzLRe2bPZB8AdYf KV1GKlRgjA3AafjwCoMrb6bfPPMOlPccINqyHJf7wFImLk6sTyVnlIVcC3FYRxK/I+RK oMz7TwhAqui3YGgDhBdnVHc208WNnfBMCPK1PdyweLbxay4CY74ytMT/P+UbPk9NVZUf EaffhOh+GrAyaklTdg4vgUmWCggtzpJHF282xqvYtlI7AyH8VX1p6/lg8twJNL7gN+Aq fT/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Lkcgr6kvMByJr04YkQx+Ocnof4wSvPnlI3aepi8aH74=; b=oQgERTciGzyiUY4t9Hzo9M/MjHpqf25UojfdRLRz87sV16PXr9ycL1rPzjdxc6vgDs gZ2LNS/XGv46mGIURUm22KX+erSXrqkC+Uaj+xsWvEDZ9IpTE8OeT6qGQcMpsjHKTIXI rnfG8UzB3LVJfG956axPjSHwLALx7oy576+dpqoaobz4KrjkqUxatHj7wfF1wfNCSaKY g80VmOYx2fhqT5r5INW+kB8sE5dFyNuhC0jFyoruJdLvAk2g+y2S/SbV1gjhT7q96q1o Wi41Lqy9EvLiQ38574SBRFbmTAc3BP9YD1Ar/s7O8sDPFauYt1ufmCkDsZZWkpusW39J Yt/A== X-Gm-Message-State: AIkVDXLBfi4ZsbK+6KBZtSb4ymAl7cx8Jsj7iu9PlVE9lFEFuaTpudbSmGYXE9NTJYqPV4mEvQxS/hBogA7KIQ== X-Received: by 10.223.170.154 with SMTP id h26mr6397317wrc.29.1486332310519; Sun, 05 Feb 2017 14:05:10 -0800 (PST) MIME-Version: 1.0 Received: by 10.28.181.147 with HTTP; Sun, 5 Feb 2017 14:05:09 -0800 (PST) Date: Sun, 5 Feb 2017 22:05:09 +0000 Message-ID: To: PHP Content-Type: multipart/alternative; boundary=94eb2c1b4fe663073d0547cfb551 Subject: [Discussion] FFI in PHP From: bowersbros@gmail.com (Alex Bowers) --94eb2c1b4fe663073d0547cfb551 Content-Type: text/plain; charset=UTF-8 Hello All, I'd like to start a discussion around an FFI RFC FFI RFC ====== There are many languages that support an FFI implementation. NodeJS Python C++ Ruby FFI allows you to call a native C function without requiring the boilerplate of an extension to be written. There are several benefits to having FFI - Performance - Shareability / Bundling - Common functionality between languages Performance === Although less pronounced than the 5.x versions, there is still a performance benefit to having native C code over PHP code. For example, you could utilise threading inside of your FFI methods, which PHP does not expose the ability to do. Shareability === If you wish to implement some of your source code in C, the current way to share it is to build it as an extension. This is cumbersome, and restricts use-cases such as shared hosting, where the ability to install your own extensions is probably restricted. However, with FFI, the shared object can be loaded from any location, and so that restriction is no longer in place. They could even be distributed via composer. Common functionality between languages === If you have some complex logic that needs to be replicated in several languages for whatever reason; implementing it several times over would lead to uncertain bugs and technical debt increasing heavily. If you could share the same logic amongst them all using FFI, then this is no longer an issue. Example === Take an example of a rust program that takes two numbers in and gives you the sum of them. ```rust #[no_mangle] pub extern fn add(a: i32, b: i32) -> i32 { a + b } ``` with the Cargo.toml file containing: ``` [package] name = "math" version = "0.1.0" authors = ["Alex Bowers "] [dependencies] [lib] name = "math" crate-type = ["dylib"] ``` `cargo build --release` will create `.so`, `.dylib`, or `.dll` files depending on your system. These should be usable within PHP using the exposed functions. ```php $math = ffi("/path/to/math.so"); $result = $math->add(1, 5); echo $result; // 6 ``` With the implementation at its most basic level, calling the `add` method with incorrect parameters would likely cause a segfault. A way around that could be that the methods are not immediately exposed, but have to be configured. Something like: ```php $math = ffi("/path/to/math.so"); $math->add(1, 5); // Throws RuntimeException, method not configured $math->configure('add', int $a, int $b); $math->add(1, 5); // 6 $math->add('a', 5); Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, string given ``` Prior art: === https://pecl.php.net/package/ffi - Last release > 13 years https://github.com/mgdm/MFFI - Not stable, last commit > 1 year, no releases --94eb2c1b4fe663073d0547cfb551--