


How to use Rust extension in PHP program, php program rust extension_PHP tutorial
How to use Rust extension in PHP program, php program rust extension
Rust in C or PHP
My basic starting point is to write some compilable Rust code into a library, write some C header files for it, and make an extension in C for the called PHP. It's not easy, but it's fun.
Rust FFI (foreign function interface)
The first thing I did was play around with Rust’s external function interface connecting Rust to C. I once wrote a flexible library using a simple method (hello_from_rust) with a single declaration (a pointer to a C char, otherwise known as a string). Here is the output of "Hello from Rust" after input.
// hello_from_rust.rs #![crate_type = "staticlib"] #![feature(libc)] extern crate libc; use std::ffi::CStr; #[no_mangle] pub extern "C" fn hello_from_rust(name: *const libc::c_char) { let buf_name = unsafe { CStr::from_ptr(name).to_bytes() }; let str_name = String::from_utf8(buf_name.to_vec()).unwrap(); let c_name = format!("Hello from Rust, {}", str_name); println!("{}", c_name); }
I split it from a Rust library called from C (or other!). Here's a good explanation of what comes next.
Compiling it will get a file of .a, libhello_from_rust.a. This is a static library that contains all its own dependencies, and we link it when compiling a C program, which allows us to do subsequent things. Note: After we compile, we will get the following output:
note: link against the following native artifacts when linking against this static library note: the order and any duplication can be significant on some platforms, and so may need to be preserved note: library: Systemnote: library: pthread note: library: c note: library: m
This is what the Rust compiler tells us to link against when we don’t use this dependency.
Call Rust from C
Now that we have a library, we have to do two things to make it callable from C. First, we need to create a C header file for it, hello_from_rust.h. Then link to it when we compile.
The following is the header file:
// hello_from_rust.h #ifndef __HELLO #define __HELLO void hello_from_rust(const char *name); #endif
This is a fairly basic header file, just providing a signature/definition for a simple function. Next we need to write a C program and use it.
// hello.c #include <stdio.h> #include <stdlib.h> #include "hello_from_rust.h" int main(int argc, char *argv[]) { hello_from_rust("Jared!"); }
We compile it by running this code:
gcc -Wall -o hello_c hello.c -L /Users/jmcfarland/code/rust/php-hello-rust -lhello_from_rust -lSystem -lpthread -lc -lm
Note that the -lSystem -lpthread -lc -lm at the end tells gcc not to link against those "native antiques" so that the Rust compiler can provide them when compiling our Rust library.
By running the following code we can get a binary file:
$ ./hello_c Hello from Rust, Jared!
Beautiful! We just called the Rust library from C. Now we need to understand how a Rust library gets into a PHP extension.
Call c from php
This part took me some time to figure out, the documentation is not the best in the world for php extensions. The best part is that the php source comes from bundling a script ext_skel (mostly stands for "Extended Skeleton") which generates most of the boilerplate code you need. You can get started by downloading the unquoted php source, writing the code into the php directory and running:
$ cd ext/ $ ./ext_skel --extname=hello_from_rust
This will generate the basic skeleton needed to create a php extension. Now, move the folders everywhere you want to keep your extensions locally. And move your
- .rust source
- .rust library
- .c header
Enter the same directory. So now you should look at a directory like this:
. ├── CREDITS ├── EXPERIMENTAL ├── config.m4 ├── config.w32 ├── hello_from_rust.c ├── hello_from_rust.h ├── hello_from_rust.php ├── hello_from_rust.rs ├── libhello_from_rust.a ├── php_hello_from_rust.h └── tests └── 001.phpt
One directory, 11 files
You can see a good description of these files in the php docs above. Create an extended file. We'll get started by editing config.m4.
Without explanation, here are my results:
PHP_ARG_WITH(hello_from_rust, for hello_from_rust support, [ --with-hello_from_rust Include hello_from_rust support]) if test "$PHP_HELLO_FROM_RUST" != "no"; then PHP_SUBST(HELLO_FROM_RUST_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(hello_from_rust, ., HELLO_FROM_RUST_SHARED_LIBADD) PHP_NEW_EXTENSION(hello_from_rust, hello_from_rust.c, $ext_shared) fi
As I understand it, these are basic macro commands. But the documentation on these macros is quite poor (for example: google "PHP_ADD_LIBRARY_WITH_PATH" does not show results written by the PHP team). I came across this PHP_ADD_LIBRARY_PATH macro in a previous thread where someone was talking about linking a static library in a PHP extension. The other recommended macros in the comments were generated after I ran ext_skel.
Now that we have the configuration setup, we need to actually call the library from the PHP script. To do this we have to modify the automatically generated file, hello_from_rust.c. First we add the hello_from_rust.h header file to the include command. Then we need to modify the definition method of confirm_hello_from_rust_compiled.
#include "hello_from_rust.h" // a bunch of comments and code removed... PHP_FUNCTION(confirm_hello_from_rust_compiled) { char *arg = NULL; int arg_len, len; char *strg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; } hello_from_rust("Jared (from PHP!!)!"); len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "hello_from_rust", arg); RETURN_STRINGL(strg, len, 0); }
Note: I added hello_from_rust("Jared (fromPHP!!)!");.
Now, we can try to build our extension:
$ phpize $ ./configure $ sudo make install
That’s it, generate our meta configuration, run the generated configuration command, and install the extension. When installing, I had to use sudo myself because my user did not own the php extension for the installation directory.
Now, we can run it!
$ php hello_from_rust.php Functions available in the test extension: confirm_hello_from_rust_compiled Hello from Rust, Jared (from PHP!!)! Congratulations! You have successfully modified ext/hello_from_rust/config.m4. Module hello_from_rust is now compiled into PHP. Segmentation fault: 11
Not bad, php has entered our c extension, seen our application method list and called it. Next, the c extension has entered our rust library and started printing our string. That's fun! But...what happened to that wrong ending?
As I mentioned, the Rust-related println! macro is used here, but I did not debug it further. If we remove this from our Rust library and return a char* replacement, the segfault disappears.
这里是 Rust 的代码:
复制代码 代码如下:
#![crate_type = "staticlib"]
#![feature(libc)]
extern crate libc;
use std::ffi::{CStr, CString};
#[no_mangle]
pub extern "C" fn hello_from_rust(name: *const libc::c_char) -> *const libc::c_char {
let buf_name = unsafe { CStr::from_ptr(name).to_bytes() };
let str_name = String::from_utf8(buf_name.to_vec()).unwrap();
let c_name = format!("Hello from Rust, {}", str_name);
CString::new(c_name).unwrap().as_ptr()
}
并变更 C 头文件:
#ifndef __HELLO #define __HELLO const char * hello_from_rust(const char *name); #endif
还要变更 C 扩展文件:
PHP_FUNCTION(confirm_hello_from_rust_compiled) { char *arg = NULL; int arg_len, len; char *strg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; } char *str; str = hello_from_rust("Jared (from PHP!!)!"); printf("%s\n", str); len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "hello_from_rust", arg); RETURN_STRINGL(strg, len, 0); }
无用的微基准
那么为什么你还要这样做?我还真的没有在现实世界里使用过这个。但是我真的认为斐波那契序列算法就是一个好的例子来说明一个PHP拓展如何很基本。通常是直截了当(在Ruby中):
def fib(at) do if (at == 1 || at == 0) return at else return fib(at - 1) + fib(at - 2) end end
而且可以通过不使用递归来改善这不好的性能:
def fib(at) do if (at == 1 || at == 0) return at elsif (val = @cache[at]).present? return val end total = 1 parent = 1 gp = 1 (1..at).each do |i| total = parent + gp gp = parent parent = total end return total end
那么我们围绕它来写两个例子,一个在PHP中,一个在Rust中。看看哪个更快。下面是PHP版:
def fib(at) do if (at == 1 || at == 0) return at elsif (val = @cache[at]).present? return val end total = 1 parent = 1 gp = 1 (1..at).each do |i| total = parent + gp gp = parent parent = total end return total end
这是它的运行结果:
$ time php php_fib.php real 0m2.046s user 0m1.823s sys 0m0.207s
现在我们来做Rust版。下面是库资源:
复制代码 代码如下:
#![crate_type = "staticlib"]
fn fib(at: usize) -> usize {
if at == 0 {
return 0;
} else if at == 1 {
return 1;
}
let mut total = 1;
let mut parent = 1;
let mut gp = 0;
for _ in 1 .. at {
total = parent + gp;
gp = parent;
parent = total;
}
return total;
}
#[no_mangle]
pub extern "C" fn rust_fib(at: usize) -> usize {
fib(at)
}
注意,我编译的库rustc - O rust_lib.rs使编译器优化(因为我们是这里的标准)。这里是C扩展源(相关摘录):
PHP_FUNCTION(confirm_rust_fib_compiled) { long number; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &number) == FAILURE) { return; } RETURN_LONG(rust_fib(number)); }
运行PHP脚本:
<?php $br = (php_sapi_name() == "cli")? "":"<br>"; if(!extension_loaded('rust_fib')) { dl('rust_fib.' . PHP_SHLIB_SUFFIX); } for ($i = 0; $i < 100000; $i ++) { confirm_rust_fib_compiled(92); } ?>
这就是它的运行结果:
$ time php rust_fib.php real 0m0.586s user 0m0.342s sys 0m0.221s
你可以看见它比前者快了三倍!完美的Rust微基准!

PHP is used to build dynamic websites, and its core functions include: 1. Generate dynamic content and generate web pages in real time by connecting with the database; 2. Process user interaction and form submissions, verify inputs and respond to operations; 3. Manage sessions and user authentication to provide a personalized experience; 4. Optimize performance and follow best practices to improve website efficiency and security.

PHP uses MySQLi and PDO extensions to interact in database operations and server-side logic processing, and processes server-side logic through functions such as session management. 1) Use MySQLi or PDO to connect to the database and execute SQL queries. 2) Handle HTTP requests and user status through session management and other functions. 3) Use transactions to ensure the atomicity of database operations. 4) Prevent SQL injection, use exception handling and closing connections for debugging. 5) Optimize performance through indexing and cache, write highly readable code and perform error handling.

Using preprocessing statements and PDO in PHP can effectively prevent SQL injection attacks. 1) Use PDO to connect to the database and set the error mode. 2) Create preprocessing statements through the prepare method and pass data using placeholders and execute methods. 3) Process query results and ensure the security and performance of the code.

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP makes it easy to create interactive web content. 1) Dynamically generate content by embedding HTML and display it in real time based on user input or database data. 2) Process form submission and generate dynamic output to ensure that htmlspecialchars is used to prevent XSS. 3) Use MySQL to create a user registration system, and use password_hash and preprocessing statements to enhance security. Mastering these techniques will improve the efficiency of web development.

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SublimeText3 English version
Recommended: Win version, supports code prompts!

SublimeText3 Mac version
God-level code editing software (SublimeText3)