• PHP-CPP开发扩展(七)


    PHP-CPP是一个用于开发PHP扩展的C++库。本节讲解一些杂项。

    读取php.ini配置

    从php.ini文件中读取设置就像从常规PHP脚本中获取这些设置一样简单。在PHP脚本中,我们可以使用内置的ini_get()函数从php.ini文件中读取设置,在C++扩展中使用Php::ini_get()函数。

    void myFunction()
    {
        // 读取 output_buffering 变量
        int output_buffering = Php::ini_get("output_buffering");
    
        // 读取 variables_order 变量
        std::string variables_order = Php::ini_get("variables_order");
    }
    

    如果需要动态注册配置,必须先使用Php::Ini进行注册:

    extension.add(Php::Ini("my_extension.var1", "default-value"));
    extension.add(Php::Ini("my_extension.var2", 12345));
    

    然后才能调用Php::ini_get()来检索当前值。

    命名空间

    添加命名空间很简单,在C++看来,命名空间只不过是类或函数前缀。如果希望类或函数出现在特定的命名空间中,则只需在类或函数名称中添加前缀即可。

    #include <phpcpp.h>
    
    void myFunction()
    {
    }
    
    extern "C" {
        PHPCPP_EXPORT void *get_module() {
    
            static Php::Extension extension("my_extension", "1.0");
    
            // 添加方法到命名空间 myNamespace
            extension.add<myFunction>("myNamespace\myFunction");
    
            return extension;
        }
    }
    
    

    也可以在get_module()使用Php::Namespace来注册类和函数:

    // 创建一个命名空间
    Php::Namespace myNamespace("myNamespace");
    
    // 添加方法到命名空间
    myNamespace.add<myFunction>("myFunction");
    
    // 注册命名空间
    extension.add(std::move(myNamespace));
    

    动态加载扩展

    在PHP代码里,我们可以使用dl()函数动态加载扩展:

    // 加载一个扩展的例子,基于操作系统
    if (!extension_loaded('sqlite')) {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            dl('php_sqlite.dll');
        } else {
            dl('sqlite.so');
        }
    }
    

    但是这个函数有使用限制,因为它的参数仅仅是要加载的扩展的文件名,这样就不能随意加载某个自定义目录上的扩展。借助php-cpp,我们可以调用Php::dl()函数,这个函数的原型是:

    Php::dl(string pathname, bool persistent)
    
    • pathname 指定扩展的名称,包含绝对路径
    • persistent 是否永久加载。默认否,当前请求结束,扩展就卸载了。

    因为pathname可以自定义路径,那么就可以动态加载任何地方的扩展了。下面是个示例:

    Php::Value enbale_dl(Php::Parameters &params)
    {
        std::string pathname = params[0];
    
        bool persistent = params.size() > 1 ? params[1].boolValue() : false;
    
        // load the extension
        return Php::dl(pathname, persistent);
    }
    
    extern "C" {
    
        PHPCPP_EXPORT void *get_module() {
            static Php::Extension myExtension("load_extension", "1.0");
    
            myExtension.add("enbale_dl", enbale_dl, {
                Php::ByVal("pathname", Php::Type::String),
                Php::ByVal("persistent", Php::Type::Bool, false)
            });
    
            return myExtension;
        }
    }
    

    使用示例:

    <?php
    
    if (!dl_unrestricted(__DIR__.'/MyExtension.so', true)) die("Extension could not be loaded");
    
    $object = new ClassFromMyExtension();
    $object->methodFromMyExtension();
    ?>
    

    系列笔记:

    参考

    1、嘉心嘉软 - SegmentFault 思否
    https://segmentfault.com/blog/jrtk
    2、A C++ library for developing PHP extensions | PHP-CPP
    http://www.php-cpp.com/documentation/introduction
    3、PHP: dl - Manual
    https://www.php.net/manual/zh/function.dl.php

  • 相关阅读:
    磁盘512n,512e,4k原生磁盘的区别和操作系统支持
    TLB与内存寻址,内存读取,虚拟内存的相关原理
    文件系统逻辑块与磁盘物理扇区的关系
    DBA的工作职责和每日工作
    理解数据库中的undo日志、redo日志、检查点
    React Native 常用插件案例
    React Native 学习资料
    React Native开源项目案例
    nginx rewrite 指令
    nginx反向代理配置
  • 原文地址:https://www.cnblogs.com/52fhy/p/12398192.html
Copyright © 2020-2023  润新知