목차
왜 PHP 확장을 사용하나요?
왜 Rust를 사용하여 PHP 확장을 개발하나요?
Rust 개발 PHP 확장 프로세스:
백엔드 개발 PHP 튜토리얼 Rust(Liunx 버전)에서 PHP 확장을 개발하는 방법을 자세히 설명하는 기사

Rust(Liunx 버전)에서 PHP 확장을 개발하는 방법을 자세히 설명하는 기사

Oct 27, 2022 pm 07:23 PM
php

Rust(Liunx 버전)에서 PHP 확장을 개발하는 방법을 자세히 설명하는 기사

우리 모두 알고 있듯이 저는 PHP 사용자로서 ffmpeg 비디오 처리 도구를 호출하는 등 PHP의 제한된 기능에 당황스럽습니다. 그것을 운영하기 위한 특별한 확장은 없습니다. 무엇입니까? PHP 시스템 함수 호출을 사용하시나요? 오픈 소스 PHP 스크립트의 경우 이는 너무 안전하지 않습니다!

이번에는 PHP 선배로서 PHP 확장 개발을 고려하고 확장에서 ffmpeg의 동작을 구현하게 됩니다.

현재 c 사이트에는 Rust에서 PHP 확장을 개발하는 방법에 대한 기사가 거의 없습니다. 심지어 PHP 확장을 개발하는 과정에 대한 기사도 다루기가 매우 어렵습니다. 이 글을 쓰고 있어요! ! !

왜 PHP 확장을 사용하나요?

장점:

1. PHP 확장은 C로 개발되었으므로 속도가 놀랍습니다.

2. 높은 결합도, 외관은 PHP를 향상시키는 데 사용됩니다.

3. 높은 보안. 결국 확장 프로그램은 컴파일된 프로그램이고 코드는 오픈 소스가 아닙니다.

단점:

1. PHP 버전과 시스템 환경에 맞춰 개발해야 하는데 그게 더 번거롭습니다. 즉, PHP 버전 7.4와 Linux 환경에서 개발된 Extension은 이 PHP 버전과 시스템만을 지원합니다.

2. C와 C++를 알아야 합니다. 물론 이 글은 Rust로 작성되었습니다. C의 데이터 유형을 이해하고 Rust FFI의 연산 및 데이터 유형 변환에 능숙해야 합니다.

3. 디버깅은 상대적으로 번거롭습니다.

왜 Rust를 사용하여 PHP 확장을 개발하나요?

이유는 아주 간단하며, Rust의 언어적 특징에 대해서도 이야기하고 있습니다.

1. "소유권" 기능으로 인해 프로그램이 더 안전하고 C와 같은 다양한 "형이상학적 버그"가 발생하지 않습니다.

2.C와 동일한 성능을 가지고 있습니다.

3. 결국 가장 인기 있는 언어이고 저는 이 언어의 발전에 대해 매우 낙관적입니다.

Rust 개발 PHP 확장 프로세스:

물론 Rust에는 현재 PHP 확장 개발을 위한 특별히 제작된 뼈대가 없습니다. 그래서 내 논리도 매우 간단합니다. 나는 Rust를 사용하여 정적 라이브러리를 개발하고 이를 C[FFI 관련 지식]에 노출합니다. 공식 PHP 뼈대에 Rust 정적 라이브러리를 직접 도입하고 해당 메서드를 호출할 수 있습니다.

개발 환경

Pagoda [CentOS 7.6], GCC [여기 시스템에 내장된 PHP 확장 뼈대 컴파일 관련, 컴파일 확장에서 오류가 보고되면 직접 설치] , 해당 PHP 버전 소스 코드 , 웹 환경 [해당 PHP 버전, nginx, mysql 등을 파고다에 설치]

전체 개발 과정:

1. 파고다 준비

Pagoda 설치 프로세스: CentOS pagoda 구축(매우 상세함)_One Code Superman's Blog-CSDN Blog_centos Pagoda

여기에서는 php7.4 확장 개발을 예로 들어보겠습니다.

2.php7.4 liunx 버전 소스 코드를 다운로드하세요

php 공식 웹사이트: PHP: Hypertext Preprocessor

주의! 소스 코드 버전은 환경의 PHP 버전과 정확히 동일해야 합니다! ! !

다운로드 완료:

3. pagoda

/usr/phper
로그인 후 복사

usr 아래에 phper 폴더를 생성한 후 여기에 소스코드 압축 패키지를 업로드하세요. .

압축된 패키지의 압축을 풉니다.

4. 자체 확장 프로그램을 만듭니다.

/usr/phper/php-7.4.30/ext 디렉토리에 이러한 PHP 파일이 있습니다. 확장 프로그램을 만들 수 있습니다!

후속 PHP 명령은 동일한 버전이어야 하므로 명령줄 버전 설정에 주의하세요!

 在刚刚的目录下,点击终端,输入创建扩展命令。

php ext_skel.php --ext 扩展名称
로그인 후 복사

 

 这里就多出了一个新的扩展源码文件。

 

 在该目录下点击终端,输入:

phpize
로그인 후 복사

 接着输入:

./configure --with-php-config=/www/server/php/74/bin/php-config
로그인 후 복사

注意这个参数php路径,如果是别的版本,请自行在宝塔里安装找到对应版本路径,它们都是放一起的。

 回车开始进行检查了

 最后输入:

make
로그인 후 복사

进行编译。

 

 这个目录下便是编译出来的so扩展最终文件了!

 让我们看下默认生成的扩展有哪些功能

 查看主文件【需了解php扩展骨架,这里以它默认给的为例】

 也就是说,刚刚编译出来的扩展,是有这两个函数的,咱们测试一下玩玩。

注意!每次修改主文件,都需要重新按上述命令跑一遍,否则不生效,很奇怪!

phpize
./configure --with-php-config=/www/server/php/74/bin/php-config
make
로그인 후 복사
로그인 후 복사

5、使用扩展

 复制刚刚生成的扩展文件到我们php环境的扩展里

 

 配置php.ini加载hello.so扩展

 

 

extension = hello.so
로그인 후 복사

保存后记得重新启动下php,否则不生效的!

 

 

在文件管理中点击终端,输入:

php -m
로그인 후 복사

可以看到我们的扩展在列表中了。

创建一个站点,测试下扩展中两个函数。

 看好,php版本是7.4

 

 访问站点

 没有问题哦!

当然也可以通过命令行运行php脚本查看结果【前提是网站那里php命令行版本设置的7.4】

php index.php
로그인 후 복사

 OK!从创建到生成到使用扩展的流程结束,接下来才进入正题,开始用rust开发扩展。

6、rust与php扩展的整合开发

开发工具:CLion

需要rust环境与CLion中rust插件的安装与配置,这个自行去百度,比我想象中的全!

 创建一个hello命名的库项目

 我们写两个导出函数,分别是加法功能和base64字符串解析功能。

 lib.rs

#![crate_type = "staticlib"]

extern crate libc;

//使用C类型约束
use std::ffi::{CStr, CString};
use libc::{c_char, c_int};

//add_int【参数:两个c语言的int类型】:对两个int类型数值进行相加
#[no_mangle]
pub extern "C" fn add_int(x:c_int, y:c_int) -> c_int{
    //两个数相加
    return x + y;
}

//base64_decode函数【参数:c语言的*char类型】:对字符串进行base64解码
#[no_mangle]
pub extern "C" fn base64_decode(s:*const c_char) -> *mut c_char {
    //c char类型转&str
    let h = unsafe{CStr::from_ptr(s).to_str().unwrap()};
    //base64 解码
    let s = base64::decode(h.to_string());
    if let Err(_s) = s {
        panic!("类型错误!");
    }
    let n = String::from_utf8(s.unwrap().clone()).unwrap();
    //String 转 C CString
    let a = CString::new(n.as_str()).unwrap();
    //C CString 转 C char
    //这里实属无奈,因为rust ffi中阐述,对字符串返回只能是该字符串地址,所以需要该方法进行返回C才能接收到!
    let r = a.into_raw();
    return r;
}
로그인 후 복사

 Cargo.toml

[package]
name = "hello"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "hello"
crate-type = ["staticlib"]

[dependencies]
libc = "*"
base64 = "0.12.1"
로그인 후 복사

注意在编译过程中涉及系统类型,不然在引入该静态库编译扩展可能报错,提示不支持。

编译64位静态库

rustup target add x86_64-unknown-linux-musl
cargo build --target x86_64-unknown-linux-musl --release
로그인 후 복사

编译32位静态库

rustup target add i686-unknown-linux-musl
cargo build --target i686-unknown-linux-musl --release
로그인 후 복사

这里我们是64位系统。

 会生成一个.a文件,该文件便是liunx支持的静态库文件。

生成支持C语言的胶水头文件【用于C调用该库需要写的函数声明,很方便】

创建cbindgen.toml文件

内容:

language = "C"
로그인 후 복사

 

 安装cbindgen,创建头文件。

cargo install --force cbindgen
cbindgen --config cbindgen.toml --crate 项目名称 --output 头文件名称.h
로그인 후 복사

 

 自动生成了C语言的函数声明hello.h文件,用于调用。

回到之前我们创建的hello扩展

创建lib文件夹

 将刚刚编译出来的静态库.a文件上传到lib目录下

 将刚刚创建的.h头文件上传到扩展目录下

 配置.m4预编译文件【关键】

 设置引入lib文件夹中的静态库文件

 

  PHP_ADD_LIBRARY_WITH_PATH(hello, /usr/phper/php-7.4.30/ext/hello/lib, HELLO_SHARED_LIBADD)
  PHP_SUBST(HELLO_SHARED_LIBADD)
로그인 후 복사

 保存.m4

 编写主文件

 

/* hello extension for PHP */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "php_hello.h"
#include "hello.h"//引入头文件
/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE() \
	ZEND_PARSE_PARAMETERS_START(0, 0) \
	ZEND_PARSE_PARAMETERS_END()
#endif

/* {{{ void hello_test1()
 */
PHP_FUNCTION(hello_test1)
{
	ZEND_PARSE_PARAMETERS_NONE();

    int num = add_int(1,2);//rust中两个数相加函数并返回。
    
	php_printf("The extension %d is loaded and working!\r\n", num);
}
/* }}} */

/* {{{ string hello_test2( [ string $var ] )
 */
PHP_FUNCTION(hello_test2)
{
	char *var = "World";
	size_t var_len = sizeof("World") - 1;
	zend_string *retval;

	ZEND_PARSE_PARAMETERS_START(0, 1)
		Z_PARAM_OPTIONAL
		Z_PARAM_STRING(var, var_len)
	ZEND_PARSE_PARAMETERS_END();

    char *newstr = base64_decode(var);//rust中解析base64字符串并返回。
    
	retval = strpprintf(0, "Hello %s", newstr);

	RETURN_STR(retval);
}
/* }}}*/

/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(hello)
{
#if defined(ZTS) && defined(COMPILE_DL_HELLO)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(hello)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "hello support", "enabled");
	php_info_print_table_end();
}
/* }}} */

/* {{{ arginfo
 */
ZEND_BEGIN_ARG_INFO(arginfo_hello_test1, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO(arginfo_hello_test2, 0)
	ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO()
/* }}} */

/* {{{ hello_functions[]
 */
static const zend_function_entry hello_functions[] = {
	PHP_FE(hello_test1,		arginfo_hello_test1)
	PHP_FE(hello_test2,		arginfo_hello_test2)
	PHP_FE_END
};
/* }}} */

/* {{{ hello_module_entry
 */
zend_module_entry hello_module_entry = {
	STANDARD_MODULE_HEADER,
	"hello",					/* Extension name */
	hello_functions,			/* zend_function_entry */
	NULL,							/* PHP_MINIT - Module initialization */
	NULL,							/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(hello),			/* PHP_RINIT - Request initialization */
	NULL,							/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(hello),			/* PHP_MINFO - Module info */
	PHP_HELLO_VERSION,		/* Version */
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_HELLO
# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
# endif
ZEND_GET_MODULE(hello)
#endif
로그인 후 복사

删除之前生成的扩展文件

 重新生成扩展

 

phpize
./configure --with-php-config=/www/server/php/74/bin/php-config
make
로그인 후 복사
로그인 후 복사

 大小都变了,说明我们的静态库在里面了哈哈。

按上述使用扩展流程替换扩展

注意!替换扩展文件后要重启PHP哦,不然不生效!

7、测试rust开发的php扩展

 

 

 网页测试

 命令行测试

 也可以通过php扩展骨架直接进行测试

 

 

 编写要执行测试的扩展函数

--TEST--
hello_test2() Basic test
--SKIPIF--
<?php
if (!extension_loaded(&#39;hello&#39;)) {
	echo &#39;skip&#39;;
}
?>
--FILE--
<?php
hello_test1();
var_dump(hello_test2(&#39;5LiA56CB6LaF5Lq6&#39;));
?>
--EXPECT--
string(11) "Hello World"
string(9) "Hello PHP"
로그인 후 복사

 扩展目录下直接输入:

make test
로그인 후 복사

 

执行后 tests目录下输出了一个.out文件

 

 是不是这样更方便了呢?

 以上就是整体的开发流程,需要经通过的话还是多少要了解C语言、php扩展骨架、rust精通。

推荐学习:《PHP视频教程

위 내용은 Rust(Liunx 버전)에서 PHP 확장을 개발하는 방법을 자세히 설명하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

cakephp4에서 날짜와 시간을 다루기 위해 사용 가능한 FrozenTime 클래스를 활용하겠습니다.

CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

파일 업로드 작업을 위해 양식 도우미를 사용할 것입니다. 다음은 파일 업로드의 예입니다.

CakePHP 유효성 검사기 만들기 CakePHP 유효성 검사기 만들기 Sep 10, 2024 pm 05:26 PM

컨트롤러에 다음 두 줄을 추가하면 유효성 검사기를 만들 수 있습니다.

CakePHP 로깅 CakePHP 로깅 Sep 10, 2024 pm 05:26 PM

CakePHP에 로그인하는 것은 매우 쉬운 작업입니다. 한 가지 기능만 사용하면 됩니다. cronjob과 같은 백그라운드 프로세스에 대해 오류, 예외, 사용자 활동, 사용자가 취한 조치를 기록할 수 있습니다. CakePHP에 데이터를 기록하는 것은 쉽습니다. log() 함수는 다음과 같습니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

CakePHP 빠른 가이드 CakePHP 빠른 가이드 Sep 10, 2024 pm 05:27 PM

CakePHP는 오픈 소스 MVC 프레임워크입니다. 이를 통해 애플리케이션 개발, 배포 및 유지 관리가 훨씬 쉬워집니다. CakePHP에는 가장 일반적인 작업의 과부하를 줄이기 위한 여러 라이브러리가 있습니다.

See all articles