威尼斯手机平台登陆-官方网站登录

威尼斯手机平台登陆为您带来世界三大博彩公司最新相关资讯,威尼斯官方网站登录充分考虑到不同地域网民的不同需求,威尼斯手机平台登陆良好的用户界面,人性化的操作,实用的功能设计使其广泛受到欢迎,推动实体出版、影视、动漫、游戏等相关文化产业的发展。

您的位置:威尼斯手机平台登陆 > 威尼斯在线注册平台 > 【威尼斯在线注册平台】为公平起见我已经更新了 PHP 和 Rust 的版本,自己总是会产生为php添加一些自定义的功能的想

【威尼斯在线注册平台】为公平起见我已经更新了 PHP 和 Rust 的版本,自己总是会产生为php添加一些自定义的功能的想

发布时间:2020-04-21 16:51编辑:威尼斯在线注册平台浏览(175)

    更新: 初藳刚发布尚未多少个小时小编开采到本人的 PHP 基准测验是错的。为公平起见自个儿已经更新了 PHP 和 Rust 的本子。你能够在 GitHub 旅舍里观察変更(链接在尾巴部分)。

    编辑本身的php扩张函数php程序写的日子长了,自然对她所提供的成效了然于目,他所提供的一大堆效果,真是感觉很好用,但有时会发觉php也缺乏一些成效,本身三番五次会发生为php增加一些自定义的效应的主见。长此以往,终于后天憋不住了,最早初始钻探怎么增加。下载叁个php的源代码包,这里运用的是php 4.0.5版,解压后会见到php的根目录下会有README.EXT_SKEL那样二个文件,展开详细阅读了弹指间,发掘了八个分外好用的工具,这一个工具得以帮你构建二个空的php扩大,然后您向在那之中加多相应的代码就能够成功你本身的意义扩大了。上边我们就来介绍怎么着运用这一个工具。首先转移你的目录到php的目录下的ext目录,倘诺您只供给三个着力的扩充框架的话,实行上面包车型客车通令:./ext_skel --extname=module_namemodule_name是您协和能够选拔的强盛模块的名字,举个例子我选拔的my_module。试行工具后会自动在ext目录下树立你接收的module_name名字的目录,里面已经转移了连带的代码,这个代码中只须求调治config.m4文件中的三行注释就可以符合规律的编写翻译带那些自定义增加模块的php了。在php的根目录施行下列操作就能够拿走。./buildconf./configure --enable-module_namemake上边小编来演示建构my_module扩张框架的全经过,为了更有机能,我们来成功贰个php的扩叶楚贵能,在php中调用那几个效应能够在web页面中呈现hello world那些优良单词。在php目录下的ext目录中,实践上边包车型客车命令./ext_skel --extname=my_module获得反馈结果:Creating directory my_moduleCreating basic files: config.m4 Makefile.in .cvsignore my_module.c php_my_module.h tests/001.phpt my_module.php [done].To use your new extension, you will have to execute the following steps:1.$ cd ..2.$ vi ext/my_module/config.m43.$ ./buildconf4.$ ./configure --[with|enable]-my_module5.$ make6.$ ./php -f ext/my_module/my_module.php7.$ vi ext/my_module/my_module.c8.$ makeRepeat steps 3-6 until you are satisfied with ext/my_module/config.m4 andstep 6 confirms that your module is compiled into PHP. Then, start writingcode and repeat the last two steps as often as necessary.假让你能看懂下面的事物,那就照着去做。借使不是老聃楚的话,遵照小编上面包车型客车提示来做也可以。Cd my_module首先步向my_module目录vi config.m4使用文本编辑器张开config.m4文件,文件内容差不离如下:dnl $Id$dnl config.m4 for extension my_modulednl don't forget to call PHP_EXTENSION(my_module)dnl Comments in this file start with the string 'dnl'.dnl Remove where necessary. This file will not workdnl without editing.dnl If your extension references something external, use with:dnl PHP_ARG_WITH(my_module, for my_module support,dnl Make sure that the comment is aligned:dnl [--with-my_module Include my_module support])dnl Otherwise use enable:dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,dnl Make sure that the comment is aligned:dnl [--enable-my_module Enable my_module support])if test "$PHP_MY_MODULE" != "no"; thendnl If you will not be testing anything external, like existence ofdnl headers, libraries or functions in them, just uncomment thednl following line and you are ready to go.dnl Write more examples of tests here...PHP_EXTENSION(my_module, $ext_shared卡塔尔(قطر‎Fi依据你自身的选料将dnl PHP_ARG_WITH(my_module, for my_module support,dnl Make sure that the comment is aligned:dnl [--with-my_module Include my_module support])修改成PHP_ARG_WITH(my_module, for my_module support,Make sure that the comment is aligned:[--with-my_module Include my_module support])或者将dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,dnl Make sure that the comment is aligned:dnl [--enable-my_module Enable my_module support])修改成PHP_ARG_ENABLE(my_module, whether to enable my_module support,Make sure that the comment is aligned:[--enable-my_module Enable my_module support]卡塔尔日常作者会选用前面一个,然后保留退出。假如你对vi文本编辑器的操作有大多不便的话,请参照他事他说加以侦察相应的注脚小说,这里就不再详细描述了。Vi my_module.c将文件之中的下列代码进行退换/* Every user visible function must have an entry in my_module_functions[].*/function_entry my_module_functions[] = { PHP_FE(say_hello, NULL)/* 增添着一溜儿代码 */ PHP_FE(confirm_my_module_compiled, NULL) /* For testing, remove later. */ {NULL, NULL, NULL} /* Must be the last line in my_module_functions[] */};在文件的结尾增多下列代码PHP_FUNCTION(say_hello){ zend_printf("hello world/n"卡塔尔;}保存文件退出vi php_my_module.h在文件中PHP_FUNCTION(confirm_my_module_compiled卡塔尔(قطر‎;一行前边加多上边包车型客车代码PHP_FUNCTION(say_hello卡塔尔国;保存文件退出退回到php的根目录下,实践下面包车型大巴命令./buildconf./configure --enable-my_modulemake假诺一切顺遂的话,大家后天已经将扩充模块my_module编写翻译到php里面了。大家编辑下边包车型大巴代码实行测量检验? Say_hello(State of Qatar;?保存文件为say_hello.php在php的根目录下运转./php q say_hello.php寻常状态下博览会示hello world表示大家的第贰个扩张正常的运营了!解释一下下边做的操作,ext_skel生成一些框下文件,大家要求改革以下文件my_module.c扩充模块的主程序php_my_module.h 扩展模块的头文件config.m4配置文件主程序中呈报了php扩张模块的扬言,模块中蕴藏多少个函数,各种函数的效果与利益,在phpinfo函数中呈现怎么内容,模块开头化做些什么,甘休做些什么都会在这里个文件里进行描述。我们在下边只是增加了叁个函数say_hello,並且描述了say_hello函数的具体内容,调用zend_printf系统函数在php中打印字符串。在对应的头文件中宣称了say_hello这些函数,进而做到了我们预料的机能。上面大家会编写三个更头眼昏花的恢弘,创立多个带参数的php扩张函数,依照给入的参数,显示hello world, xxxx。Xxxx代表输入的字符串内容,例如小编的名字yorgo。Vi my_module.c修改最终的say_hello函数内容如下:PHP_FUNCTION(say_hello){ zval **yourname; if (ZEND_NUM_ARGS() != 1 zend_get_parameters_ex(1, &yourname) == FAILURE) { WRONG_PARAM_COUNT; } zend_printf("hello world, %s/n", Z_STRVAL_PP(yournameState of Qatar卡塔尔;}存盘退出。退回php的根目录,运转make更改say_hello.php为? Say_hello(“yorgo”卡塔尔;?保存退出后运维./php q say_hello.php得出结果hello world, yorgo代表我们本次的校订也成功了,能够变动say_hello中的参数,看看动态的效果与利益。这里根本表达上边修正的函数内容,由于say_hello函数要求有参数引进,所以在my_module.c中的say_hello函数主要在展开参数的拍卖,将php中援引say_hello时所填写的参数内容科学的传递到my_module.c中的say_hello管理函数中。为此,程序中增多了那般几行。zval **yourname;if (ZEND_NUM_ARGS() != 1 zend_get_parameters_ex(1, &yourname) == FAILURE){WRONG_PARAM_COUNT;}zend_printf("hello world, %s/n", Z_STRVAL_PP(yourname卡塔尔State of Qatar;代码解释如下:zval **yourname;起初化一个参数的指针ZEND_NUM_AENCOREGS(卡塔尔获得传递过来得参数数量,并且判断借使不为1的时候表示有标题,报错。zend_get_parameters_ex(1, &yournameState of Qatar将刚刚先河化的指针指向传递过来的参数,若是不成功则报错。Z_STRVAL_PP(yournameState of Qatar管理指针指向的参数并收获实际存款和储蓄的值。(待续卡塔尔国

    2018年四月,作者和 Etsy 的同事有过一个有关什么为像PHP样的解释性语言写扩充的座谈,Ruby或Python近日的光景相应会比PHP轻松。大家谈起了写一个得逞创办扩张的阻碍是它们平常必要用C来写,可是一旦你不专长C那门语言的话很难有充裕信心。

    从当时起作者便萌生了用Rust写二个的主见,过去的几天一直在品味。今天早晨笔者到底让它运行了。

    C或PHP中的Rust

    自个儿的中坚出发点就是写一些足以编写翻译的Rust代码到二个Curry面,并写为它有些C的头文件,在C中为被调用的PHP做二个扩充。固然并非非常粗大略,但是很风趣。

    Rust FFI(foreign function interface)

    本人所做的率先件业务便是摆弄Rust与C连接的Rust的外部函数接口。笔者曾用简易的情势(hello_from_rust)写过两个灵活的库,伴有单纯的注解(a pointer to a C char, otherwise known as a string),如下是输入后输出的“Hello from Rust”。

    // 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);
    }
    

    本身从C(或此外!)中调用的Rust库拆分它。那有叁个接下去会怎么着的很好的讲解。

    编写翻译它会得到.a的二个文件,libhello_from_rust.a。那是二个静态的库,包涵它和谐具有的信赖关系,何况大家在编译多个C程序的时候链接它,那让我们能做继续的专业。注意:在我们编写翻译后会获得如下输出:

    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
    

    那就是Rust编写翻译器在我们不行使那一个凭借的时候所告诉我们须要链接什么。

    从C中调用Rust

    既然我们有了叁个库,一定要做两件事来确定保证它从C中可调用。首先,大家必要为它创设二个C的头文件,hello_from_rust.h。然后在我们编译的时候链接到它。

    下边是头文件:

    // hello_from_rust.h
    #ifndef __HELLO
    #define __HELLO
    
    void hello_from_rust(const char *name);
    
    #endif
    

    那是贰个一定底工的头文件,仅仅为了三个精短的函数提供签名/定义。接着大家须求写一个C程序并运用它。

    // hello.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "hello_from_rust.h"
    
    int main(int argc, char *argv[]) {
        hello_from_rust("Jared!");
    }
    

    作者们由此运维一下代码来编写翻译它:

    gcc -Wall -o hello_c hello.c -L /Users/jmcfarland/code/rust/php-hello-rust -lhello_from_rust -lSystem -lpthread -lc -lm
    

    在意在终极的-lSystem -lpthread -lc -lm告诉gcc不要链接那么些“本地的古物”,为了当编写翻译大家的Rust库时Rust编写翻译器能够提供出来。

    经运维下边包车型客车代码大家得以获得叁个二进制的文书:

    $ ./hello_c
    Hello from Rust, Jared!
    

    美貌!大家刚刚从C中调用了Rust库。现在大家供给领悟Rust库是如何进入四个PHP扩充的。

    从 php 中调用 c

    该片段花了作者有的时光来弄掌握,在此个世界上,该文书档案在 php 扩张中并非最佳的。最佳的一对是来自绑定多个本子 ext_skel 的 php 源(大多数表示“扩充骨架”)即生成大大多你要求的样子代码。为了让代码运维,笔者充裕着力地读书 php 文档,“增加骨骼”。

    您能够由此下载来开头,和未分配的定额的 php 源,把代码写进 php 目录而且运营:

    $ cd ext/
    $ ./ext_skel –extname=hello_from_rust

    那将转移供给创立 php 增加的主旨骨架。未来,移动你随地想有的地保全您的扩充的公文夹。并且一抬手一动脚你的

    .rust 源

    .rust库

    .c header

    步入同三个索引。因此,以后你应当看看像那样的一个索引:

    .
    ├── 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

    三个索引,拾一个公文

    您能够在 php docs 在地点见到有关那一个文件很好的陈诉。建构三个扩张的文书。大家将经过编写制定config.m4 来开始吧。

    不表明,上边便是本身的果实:

    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
    

    正如作者所精通的那样,这一个是基本的宏命令。可是至于那一个宏命令的文书档案是一对一倒霉的(比如:google”PHP_ADD_LIBRARY_WITH_PATH”并未有现身PHP共青团和少先队所写的结果)。作者临时这一个PHP_ADD_LIBRARY_PATH宏命令在有一点点人所研讨的在三个PHP拓宽里链接叁个静态库的先前的线程里。在口不择言中别的的推荐使用的宏命令是在自家运营ext_skel后爆发的。

    既然大家开展了陈设安装,大家须要从PHP脚本中实际上地调用库。为此大家得校勘自动生成的文书,hello_from_rust.c。首先我们增多hello_from_rust.h头文件到含有命令中。然后大家要改善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);
    }
    

    留心:笔者增多了hello_from_rust(“Jared (fromPHP!!)!”);。

    现行,大家得以试着创建大家的扩展:

    $ phpize
    $ ./configure
    $ sudo make install

    便是它,生成我们的元配置,运转生成的配备命令,然后安装该扩大。安装时,作者必需亲自使用sudo,因为小编的客户并不具备安装目录的 php 扩充。

    明天,我们得以运作它啦!

    $ 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

    还不易,php 已跻身我们的 c 扩充,见到大家的施用措施列表何况调用。接着,c 扩充已走入大家的 rust 库,开首打字与印刷大家的字符串。那很有趣!可是……这段错误的结果发生了如何?

     

    正如本身所关联的,这里是应用了 Rust 相关的 println! 宏,不过小编未有对它做越来越调理。如若大家从大家的 Rust 库中去除并赶回二个 char* 代替,段错误就能消退。

    这里是 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微基准!

    总结

    此处大概一直不搜查缴获什么结论。笔者不鲜明在Rust上写三个PHP的恢弘是叁个好的主张,可是花费一些时间去研讨Rust,PHP和C,那是一个很好的主意。

    如果您愿意查看全体代码或许查看改过记录,能够访谈GitHub Repo。

    本文由威尼斯手机平台登陆发布于威尼斯在线注册平台,转载请注明出处:【威尼斯在线注册平台】为公平起见我已经更新了 PHP 和 Rust 的版本,自己总是会产生为php添加一些自定义的功能的想

    关键词:

上一篇:没有了

下一篇:没有了