phpy:PHP与Python互调用库,为PHP引入Python生态,PHP也可以写AI了

8861次阅读 732人点赞 作者: WuBin 发布时间: 2023-12-21 14:25:29
扫码到手机查看

编译安装

phpy 是识沃团队最新推出的开源项目,目标是为PHP引入Python生态,来弥补PHP生态的空缺和不足。phpy使得PHP可以调用所有Python的包。

包括当下非常流行的PyTorchtransformersTensorFlowAI库,以及NumpyPandasScikit等科学计算库,还可以使用PyQtwxPython等图形界面库。

  • GitHub 地址:https://github.com/swoole/phpy

不建议在php-fpm/apache短生命周期运行环境下使用,频繁地导入/销毁模块的开销会消耗大量资源

phpy可以作为PHP的扩展,也可以作为PythonC模块。既可以在PHP代码中调用Python的库,也可以在Python中调用PHP的类和函数。

作为Python模块时依赖PHPembed SAPI,检查PHP的目录中,确保存在libphp.so
ll /opt/php-8.1/lib/libphp.so
-rwxr-xr-x 1 htf htf 39397224 11 30 19:25 /opt/php-8.1/lib/libphp.so*

编译依赖

  1. Python 3.10或以上版本,建议使用conda工具来安装

  2. PHP 8.1或以上版本

Python将安装到/opt/anaconda3目录下

  • /opt/anaconda3/bin/pythonPython主程序

  • /opt/anaconda3/include/python3.11头文件

  • /opt/anaconda3/lib/python3.11动态链接库目录

另外需要配置/etc/ld.so.conf.d/conda.conf加入/opt/anaconda3/lib/opt/php-8.1/lib。执行ldconfig检查是否可以找到libpython3.11.solibphp.so
udo ldconfig -p |grep php
    libphp7.so (libc6,x86-64) => /opt/php-7.4/lib/libphp7.so
    libphp.so (libc6,x86-64) => /opt/php-8.0/lib/libphp.so
    
sudo ldconfig -p |grep python
    libsamba-policy.cpython-38-x86-64-linux-gnu.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libsamba-policy.cpython-38-x86-64-linux-gnu.so.0
    libpython3.11.so.1.0 (libc6,x86-64) => /opt/anaconda3/lib/libpython3.11.so.1.0
    libpython3.11.so (libc6,x86-64) => /opt/anaconda3/lib/libpython3.11.so
    libpython3.8.so.1.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libpython3.8.so.1.0
    libpython3.8.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libpython3.8.so
    libpython3.5m.so.1.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0
    libpython3.so (libc6,x86-64) => /opt/anaconda3/lib/libpython3.so
    libpython2.7.so.1.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0
    libpython2.7.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libpython2.7.so

作为PHP扩展

检查config.m4Python路径是否正确。若Python的安装路径不是/opt/anaconda3,需修改为正确的安装路径。
cd phpy
phpize
./configure
make install

安装成功后,修改php.ini,加入extension=phpy.so,执行php -mphp --ri phpy检查是否成功加载扩展。

作为Python模块

cmake .
make -j

执行成功后,会生成tests/lib/phpy.so文件。可以在Python中直接导入此模块。

import phpy

使用方法

导入 Python 模块

$os = PyCore::import('os');

执行函数

$uname = $os->uname();

读取属性

echo $uname->sysname;

加载路径

可使用PyCore::import('sys')->path->append()将一些目录加入到加载路径列表中。例如:/workspace/app/user.py自定义的包,可以通过下面的步骤实现加载:

  1. PyCore::import('sys')->path->append('/workspace')/workspace添加到sys.path

  2. PyCore::import('app.user')将自动搜索sys.path找到对应的app/user.py包并载入

内置方法

  • PyCore::str()将对象转为字符串

  • PyCore::repr()

  • PyCore::type()获取对象的类型

  • PyCore::locals()获取当前空间内容的所有局部变量

  • PyCore::globals()获取所有全局变量

  • PyCore::hash()获取 Hash 值

  • PyCore::hasattr()检测对象是否存在某个属性

  • PyCore::id()获取对象的内部编号

  • PyCore::len()获取长度

  • PyCore::dir()获取对象所有的属性、方法

  • PyCore::int()构造一个整数

  • PyCore::float()构造一个浮点数

  • PyCore::fn()构造一个可调用函数

  • PyCore::scalar()PyObject对象转为PHP的标量类型,例如PyStr将转为PHP 字符串Dict/Tuple/Set/List将转为Array

内置类

  • PyObject:所有其他类型的基类

  • PyDict:字典类型,等同于PHP的关联数组

  • PyList:列表类型,等同于PHP的索引数组

  • PyTuple:元组,不可变的列表

  • PyStr:字符串

  • PyModulePython包,PyModule也是PyObject的子类

PyObject是除了PyCore之外,所有其他类型的基类。非内置类的对象是PyObject的实例。PyObject实现了4个魔术方法,用于将操作映射到Python对象。

所有类方法、参数、返回值参考stubs目录中的文件。

继承关系

PyObject -> PyModule
         -> PySequenece -> PyList
                        -> PyTuple
         -> PySet
         -> PyStr
         -> PyDict
         -> PyType

整数

ython语言是天然支持无限精度整型计算的,可以使用Python的整数计算能力来代替ext-bcmath

构造

使用PyCore::int()函数来构造一个数字,可以传入整数、浮点数、字符串来初始化。

$i1 = PyCore::int(12345678);
$i2 = PyCore::int('1234567890123456789012345678901234567890');
$i3 = PyCore::int(12345678.03);

运算

整数同样也是PyObject的实例,可以使用内置的方法类实现运算。

$i = PyCore::int(12345435);
var_dump(strval($i->__pow__(3)));
var_dump(strval($i->__add__(4)));

将输出1881564851360655187875,由于超过了64位最大精度,因此输出结果将自动转为字符串类型。

命名参数

phpy支持了命名参数,可以使用命名参数来调用Python的函数和方法。

顺序参数必须在前,命名参数必须在最后
kwargs($a, $b, $c, name: 'hello', world: 'rango');

对应的Python代码为:

kwargs(a, b, c, name: 'hello', world: 'rango')

回调函数

可将PHP的可调用对象作为Python的回调函数。使用PyCore::fn(callable $fn)包裹即可。

$m = PyCore::import('app.user');
$uuid = uniqid();
$rs = $m->test_callback(PyCore::fn(function ($namespace) use ($uuid) {
    var_dump($namespace);
    return $uuid;
}));
  • import app.user导入了一个自定义Python

  • 调用了包中的一个函数test_callback,此函数接受一个参数为Python Callable对象

  • 使用PyCore::fn()包裹了一个Closure闭包对象作为回调,这里也支持函数名称字符串、对象方法的调用方式

  • 回调函数返回了一个字符串,在test_callback函数中会得到一个str类型返回值

实际案例

基于tkinter实现GUI的例子

<?php
$tkinter = PyCore::import('tkinter');
$root = $tkinter->Tk();
$root->title('我的窗口');
$root->geometry("500x500");
$root->resizable(False, False);

$button = $tkinter->Button($root, text: "Click Me!!", command: PyCore::fn(function () {
    var_dump(func_get_args());
    echo 'click me!!' . PHP_EOL;
}));
$button->pack();

$tkinter->mainloop();

一个基于transformers的情感分析模型推理实现

<?php
$transformers = PyCore::import('transformers');

$os = PyCore::import('os');
$os->environ->__setitem__('https_proxy', getenv('https_proxy'));

$distilled_student_sentiment_classifier = $transformers->pipeline(
    model: "lxyuan/distilbert-base-multilingual-cased-sentiments-student",
    top_k: null,
);

$rs = $distilled_student_sentiment_classifier ("I love this movie and i would watch it again and again!");
var_dump(PyCore::scalar($rs));

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:phpy
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    8326次阅读 530人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3418次阅读 252人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    13389次阅读 866人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12205次阅读 392人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    10543次阅读 843人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    14427次阅读 1150人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14316次阅读 1166人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    27403次阅读 2153人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    23552次阅读 1814人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录