php7.4 ffi,PHP7.4 全新扩展方式 FFI 详解

变量提升:先获取变量再执行

标签:label

可以用于跳出代码块

foo: {

console.log(1);

break foo;

console.log('本行不会输出');

}

console.log(2);

// 1

// 2

typeof 运算符 确定变量类型

typeof window

typeof {}

typeof []

typeof null

以上都是Object类型

null表示一个空对象,转为数值为0

undefined是一个表示 此处无定义的原始值 转为数值为NaN

undefined,null,false,0,NaN,""或''都为false, 其他为true

NaN的数据类型依然属于Number,NaN不等于任何值,包括它本身

Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)

Infinity与NaN比较,总是返回false。

parselnt()用于将字符串转为整数

parseFloat()用于将一个字符串转为浮点数

isNaN()判断一个值是都为NaN

_SSL_VERIFYPEER = 64;

const CURLOPT_WRITEDATA = 10001;

const CURLOPT_WRITEFUNCTION = 20011;

$libcurl = FFI::scope("libcurl");

$write = FFI::scope("write");

$url = "https://www.laruence.com/2020/03/11/5475.html";

$data = $write->new("own_write_data");

$ch = $libcurl->curl_easy_init();

$libcurl->curl_easy_setopt($ch, CURLOPT_URL, $url);

$libcurl->curl_easy_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

$libcurl->curl_easy_setopt($ch, CURLOPT_WRITEDATA, FFI::addr($data));

$libcurl->curl_easy_setopt($ch, CURLOPT_WRITEFUNCTION, $write->init());

$libcurl->curl_easy_perform($ch);

$libcurl->curl_easy_cleanup($ch);

ret = FFI::string($data->buf, $data->size);

也就是,我们现在使用

FFI :: scope

来代替

FFI :: load

,引用对应的函数。

static

?

function

?

scope(string $name): FFI;

然后还有另外一个问题,FFI虽然给了我们很大的规模,但是毕竟直接调用C库函数,还是非常具有风险性的,我们应该只允许用户调用我们确认过的函数,于是,

ffi.enable = preload

就该上场了,当我们设置

ffi.enable = preload

的话,那就只有在

opcache.preload

的脚本中的函数才能调用FFI,而用户写的函数是没有办法直接调用的。

我们稍微修改下

ffi_preload.inc

变成

ffi_safe_preload.inc

< php

class CURLOPT {

const URL = 10002;

const SSL_VERIFYHOST = 81;

const SSL_VERIFYPEER = 64;

const WRITEDATA = 10001;

const WRITEFUNCTION = 20011;

}

FFI::load("curl.h");

FFI::load("write.h");

function get_libcurl() : FFI {

return FFI::scope("libcurl");

}

function get_write_data($write) : FFICData {

return $write->new("own_write_data");

}

function get_write() : FFI {

return FFI::scope("write");

}

function get_data_addr($data) : FFICData {

return FFI::addr($data);

}

function paser_libcurl_ret($data) :string{

return FFI::string($data->buf, $data->size);

}

也就是,我们把所有会调用FFI API的函数都定义在

preload

脚本中,然后我们的示例会变成(

ffi_safe.php

):

< php

$libcurl = get_libcurl();

$write =  get_write();

$data = get_write_data($write);

$url = "https://www.laruence.com/2020/03/11/5475.html";

$ch = $libcurl->curl_easy_init();

$libcurl->curl_easy_setopt($ch, CURLOPT::URL, $url);

$libcurl->curl_easy_setopt($ch, CURLOPT::SSL_VERIFYPEER, 0);

$libcurl->curl_easy_setopt($ch, CURLOPT::WRITEDATA, get_data_addr($data));

$libcurl->curl_easy_setopt($ch, CURLOPT::WRITEFUNCTION, $write->init());

$libcurl->curl_easy_perform($ch);

$libcurl->curl_easy_cleanup($ch);

$ret = paser_libcurl_ret($data);

这样一来通过

ffi.enable = preload

,我们就可以限制,所有的FFI API只能被我们可控制的

preload

脚本调用,用户不能直接调用。从而我们可以在这些函数内部做好适当的安全保证工作,从而保证一定的安全性。

好了,经历了这个例子,大家应该对FFI有一个比较深入的理解了,详细的PHP API说明,大家可以参考:PHP-FFI Manual,有兴趣的话,就去找一个C库,试试吧?

本文的例子,你可以在我的github上下载到:FFI example

最后还是多说一句,例子只是为了演示功能,所以省掉了很多错误分支的判断捕获,大家自己写的时候还是要加入。毕竟使用FFI的话,会让你会有1000种方式让PHP segfault crash,所以be careful

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值