phpy之PHP與Python互調(diào)庫(kù)實(shí)現(xiàn)AI編程
phpy
phpy 是識(shí)沃團(tuán)隊(duì)最新推出的開(kāi)源項(xiàng)目,目標(biāo)是為 PHP
引入 Python
生態(tài),來(lái)彌補(bǔ) PHP
生態(tài)的空缺和不足。phpy
使得 PHP
可以調(diào)用所有 Python
的包。
包括當(dāng)下非常流行的 PyTorch
、transformers
、TensorFlow
等 AI
庫(kù),以及 Numpy
、Pandas
、Scikit
等科學(xué)計(jì)算庫(kù),還可以使用 PyQt
、wxPython
等圖形界面庫(kù)。
- GitHub 地址:https://github.com/swoole/phpy
不建議在 php-fpm/apache 短生命周期運(yùn)行環(huán)境下使用,頻繁地導(dǎo)入/銷毀模塊的開(kāi)銷會(huì)消耗大量資源
編譯安裝
phpy
可以作為 PHP
的擴(kuò)展,也可以作為 Python
的 C
模塊。既可以在 PHP
代碼中調(diào)用 Python
的庫(kù),也可以在 Python
中調(diào)用 PHP
的類和函數(shù)。
作為 Python
模塊時(shí)依賴 PHP
的 embed 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*
編譯依賴
Python 3.10
或以上版本,建議使用conda
工具來(lái)安裝PHP 8.1
或以上版本
Python
將安裝到 /opt/anaconda3
目錄下
/opt/anaconda3/bin/python
Python
主程序/opt/anaconda3/include/python3.11
頭文件/opt/anaconda3/lib/python3.11
動(dòng)態(tài)鏈接庫(kù)目錄
另外需要配置 /etc/ld.so.conf.d/conda.conf
加入 /opt/anaconda3/lib
和 /opt/php-8.1/lib
。執(zhí)行 ldconfig
檢查是否可以找到 libpython3.11.so
和 libphp.so
。
sudo 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 擴(kuò)展
檢查 config.m4
中 Python
路徑是否正確。若 Python
的安裝路徑不是 /opt/anaconda3
,需修改為正確的安裝路徑。
cd phpy phpize ./configure make install
安裝成功后,修改 php.ini
,加入 extension=phpy.so
,執(zhí)行 php -m
和 php --ri phpy
檢查是否成功加載擴(kuò)展。
作為 Python 模塊
cmake . make -j
執(zhí)行成功后,會(huì)生成 tests/lib/phpy.so
文件??梢栽?nbsp;Python
中直接導(dǎo)入此模塊。
import phpy
使用方法
導(dǎo)入 Python 模塊
$os = PyCore::import('os');
執(zhí)行函數(shù)
$uname = $os->uname();
讀取屬性
echo $uname->sysname;
加載路徑
可使用 PyCore::import('sys')->path->append()
將一些目錄加入到加載路徑列表中。
例如:/workspace/app/user.py
自定義的包,可以通過(guò)下面的步驟實(shí)現(xiàn)加載:
PyCore::import('sys')->path->append('/workspace')
將/workspace
添加到sys.path
中PyCore::import('app.user')
將自動(dòng)搜索sys.path
找到對(duì)應(yīng)的app/user.py
包并載入
內(nèi)置方法
PyCore::str()
將對(duì)象轉(zhuǎn)為字符串PyCore::repr()
PyCore::type()
獲取對(duì)象的類型PyCore::locals()
獲取當(dāng)前空間內(nèi)容的所有局部變量PyCore::globals()
獲取所有全局變量PyCore::hash()
獲取 Hash 值PyCore::hasattr()
檢測(cè)對(duì)象是否存在某個(gè)屬性PyCore::id()
獲取對(duì)象的內(nèi)部編號(hào)PyCore::len()
獲取長(zhǎng)度PyCore::dir()
獲取對(duì)象所有的屬性、方法PyCore::int()
構(gòu)造一個(gè)整數(shù)PyCore::float()
構(gòu)造一個(gè)浮點(diǎn)數(shù)PyCore::fn()
構(gòu)造一個(gè)可調(diào)用函數(shù)PyCore::scalar()
將PyObject
對(duì)象轉(zhuǎn)為PHP
的標(biāo)量類型,例如PyStr
將轉(zhuǎn)為PHP 字符串
,Dict/Tuple/Set/List
將轉(zhuǎn)為Array
內(nèi)置類
PyObject
:所有其他類型的基類PyDict
:字典類型,等同于PHP
的關(guān)聯(lián)數(shù)組PyList
:列表類型,等同于PHP
的索引數(shù)組PyTuple
:元組,不可變的列表PyStr
:字符串PyModule
:Python
包,PyModule
也是PyObject
的子類
PyObject
是除了 PyCore
之外,所有其他類型的基類。非內(nèi)置類的對(duì)象是 PyObject
的實(shí)例。PyObject
實(shí)現(xiàn)了 4
個(gè)魔術(shù)方法,用于將操作映射到 Python
對(duì)象。
所有類方法、參數(shù)、返回值參考 stubs
目錄中的文件。
繼承關(guān)系
PyObject -> PyModule -> PySequenece -> PyList -> PyTuple -> PySet -> PyStr -> PyDict -> PyType
整數(shù)
Python
語(yǔ)言是天然支持無(wú)限精度整型計(jì)算的,可以使用 Python
的整數(shù)計(jì)算能力來(lái)代替 ext-bcmath
構(gòu)造
使用 PyCore::int()
函數(shù)來(lái)構(gòu)造一個(gè)數(shù)字,可以傳入整數(shù)、浮點(diǎn)數(shù)、字符串來(lái)初始化。
$i1 = PyCore::int(12345678); $i2 = PyCore::int('1234567890123456789012345678901234567890'); $i3 = PyCore::int(12345678.03);
運(yùn)算
整數(shù)同樣也是 PyObject
的實(shí)例,可以使用內(nèi)置的方法類實(shí)現(xiàn)運(yùn)算。
$i = PyCore::int(12345435); var_dump(strval($i->__pow__(3))); var_dump(strval($i->__add__(4)));
將輸出 1881564851360655187875
,由于超過(guò)了 64位
最大精度,因此輸出結(jié)果將自動(dòng)轉(zhuǎn)為字符串類型。
命名參數(shù)
phpy
支持了命名參數(shù),可以使用命名參數(shù)來(lái)調(diào)用 Python
的函數(shù)和方法。
順序參數(shù)必須在前,命名參數(shù)必須在最后
kwargs($a, $b, $c, name: 'hello', world: 'rango');
對(duì)應(yīng)的 Python
代碼為:
kwargs(a, b, c, name: 'hello', world: 'rango')
回調(diào)函數(shù)
可將 PHP
的可調(diào)用對(duì)象作為 Python
的回調(diào)函數(shù)。使用 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
導(dǎo)入了一個(gè)自定義Python
包- 調(diào)用了包中的一個(gè)函數(shù)
test_callback
,此函數(shù)接受一個(gè)參數(shù)為Python Callable
對(duì)象 - 使用
PyCore::fn()
包裹了一個(gè)Closure
閉包對(duì)象作為回調(diào),這里也支持函數(shù)名稱字符串、對(duì)象方法的調(diào)用方式 - 回調(diào)函數(shù)返回了一個(gè)字符串,在
test_callback
函數(shù)中會(huì)得到一個(gè)str
類型返回值
可參考下方的 Python tkinter
例子。
實(shí)際案例
基于 tkinter 實(shí)現(xiàn) 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();
一個(gè)基于 transformers 的情感分析模型推理實(shí)現(xiàn)
<?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之PHP與Python互調(diào)庫(kù)實(shí)現(xiàn)AI編程的詳細(xì)內(nèi)容,更多關(guān)于phpy PHP與Python互調(diào)庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PHP實(shí)現(xiàn)限制IP訪問(wèn)及提交次數(shù)的方法詳解
這篇文章主要介紹了PHP實(shí)現(xiàn)限制IP訪問(wèn)及提交次數(shù)的方法,涉及php針對(duì)客戶端來(lái)訪IP的獲取、判斷以及結(jié)合session記錄IP訪問(wèn)次數(shù)等相關(guān)操作技巧,需要的朋友可以參考下2017-07-07使用PHP獲取網(wǎng)絡(luò)文件的實(shí)現(xiàn)代碼
PHP獲取網(wǎng)絡(luò)文件的實(shí)現(xiàn)代碼,其實(shí)就是一個(gè)小偷程序。學(xué)習(xí)php小偷程序的朋友可以參考下。2010-01-01PHP創(chuàng)建文件及寫入數(shù)據(jù)(覆蓋寫入,追加寫入)的方法詳解
這篇文章主要介紹了PHP創(chuàng)建文件及寫入數(shù)據(jù)(覆蓋寫入,追加寫入)的方法,結(jié)合實(shí)例形式總結(jié)分析了php文件創(chuàng)建、寫入操作相關(guān)函數(shù)使用技巧,需要的朋友可以參考下2019-02-02PHP棧的定義、入棧出棧方法及基于堆棧實(shí)現(xiàn)的計(jì)算器完整實(shí)例
這篇文章主要介紹了PHP棧的定義、入棧出棧方法及基于堆棧實(shí)現(xiàn)的計(jì)算器,結(jié)合實(shí)例形式較為詳細(xì)的分析了php定義與使用棧的基本方法,并結(jié)合完整實(shí)例形式給出了php基于堆棧實(shí)現(xiàn)高級(jí)計(jì)算器功能的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11php中如何判斷一個(gè)網(wǎng)頁(yè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求
以下是對(duì)php中如何判斷一個(gè)網(wǎng)頁(yè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08PHP表單提交表單名稱含有點(diǎn)號(hào)(.)則會(huì)被轉(zhuǎn)化為下劃線(_)
做項(xiàng)目的過(guò)程中發(fā)現(xiàn),表單遞交就是不成功,后來(lái)發(fā)現(xiàn)原來(lái)我給控件的名字不規(guī)范導(dǎo)致,控件遞交到后端之后,發(fā)現(xiàn)所有我控件名字中含有.號(hào)的名字,遞交過(guò)之后都會(huì)被轉(zhuǎn)化成下劃線_2011-12-12windows下PHP_intl.dll正確配置方法(apache2.2+php5.3.5)
配置php_intl模塊總是加載失敗,在這找到了解決方法2014-01-01