溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PPython的原理和架構(gòu)介紹

發(fā)布時間:2021-09-04 11:54:20 來源:億速云 閱讀:195 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“PPython的原理和架構(gòu)介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“PPython的原理和架構(gòu)介紹”吧!

介紹

Python 與 PHP 都是廣泛使用的語言,各有所長,讓人期待兩者結(jié)合可以實現(xiàn)更豐富的效果。

在 PHP 中調(diào)用 Python 實現(xiàn)某些處理,這種需求雖然比較小眾,還是實用的。目前網(wǎng)上可以查到很多資料仍在探討 exec()(也包括 system()shell_exec()、passthru() 等)執(zhí)行外部的 Python 文件,但這只是一種通用的方式,調(diào)用成本比較高,在每次調(diào)用時,需要裝載整個 Python 解釋環(huán)境。

有此類需求的開發(fā)者非常適合看一下 PPython,這是一種從根本上將 PHP 與 Python 有效結(jié)合的技術(shù)。

PPython 最初見于 https://code.google.com/p/ppython,該作者將 lajp(一種 PHP 結(jié)合 Java 的技術(shù))移植到了 Python 上。

該項目最初建立于 2012 年,而且似乎已經(jīng)停止維護多年,不過目前來看其思路及效果還是值得肯定的,因此將此項目從停止運營的 Google Code 上遷移到了 GitHub,并遵循原 Apache 許可證重新發(fā)布和維護。

日前筆者對此作了一番嘗試,對 PPython 的方便易用有所體會。

原理與架構(gòu)

PHP 與 Python 通訊有兩種不同的套接字機制:TCP 套接字和 UNIX 套接字。UNIX 套接字是 Unix/Linux 本地套接字,相對于 TCP 套接字,具有以下特點:

  • 只能在同一臺主機中通訊(IPC),不能跨主機;

  • 傳輸速度大于 TCP 套接字;

  • 服務(wù)端只向本機提供服務(wù)(沒有對外偵聽端口),相對安全,易于管理。

PHP 和 Python 各有其語言內(nèi)部定義的數(shù)據(jù)類型,通常 PHP 進程與 Python 進程進行數(shù)據(jù)交互時,需要進行轉(zhuǎn)碼處理。此類轉(zhuǎn)換如由應(yīng)用自行實現(xiàn),從開發(fā)效率到運行性能都會增加不少額外負(fù)擔(dān)。

PPython 對 PHP 和 Python 間的通訊方式的處理支持 TCP 套接字和 UNIX 套接字兩種機制,兼顧通訊效率和分布式,轉(zhuǎn)碼由服務(wù)統(tǒng)一處理,Python 為 PHP 的數(shù)據(jù)類型提供格式兼容,使 PHP 端開發(fā)無須為底層通訊擔(dān)心。

Python 因其語言 GIL 特性,同一進程內(nèi)多線程效率不高。PPython 可根據(jù)項目需要部署服務(wù),多進程運行 Python,提高應(yīng)用綜合性能。

PPython的原理和架構(gòu)介紹

使用方法

PPython 的代碼可從上述項目倉庫中下載。

下載得到的文件中,以下三個是 PPython 的核心代碼,作用如下:

  • php_python.py,Python 進程主文件,完成 Python 端監(jiān)聽請求并運行返回

  • process.py,Python 端核心類,實現(xiàn) Python 內(nèi)部進程調(diào)用及 PHP 與 Python 數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化等關(guān)鍵處理

  • php_python.php,PPython 客戶端,PHP 端引用此文件,可直接使用 PPython 函數(shù)實現(xiàn)調(diào)用。

將以上文件放置到任意目錄。先修改準(zhǔn)備運行 PPython 的端口,監(jiān)聽端口不限,只要 php_python.pyphp_python.php 兩端修改一致。筆者統(tǒng)一改為 10240。

在當(dāng)前目錄下運行 php_python.py,只要 Python 環(huán)境正常,便將運行起一個 PPython 的服務(wù)。

-------------------------------------------- PPython Service- Time: 2019-05-13 22:24:09-------------------------------------------Listen port: 10240charset: utf-8Server startup...

PHP 端引入 php_python.php,就可以用 ppython 函數(shù)與之前啟動的 PPython 服務(wù)通訊,傳入請求由 PPython 服務(wù)調(diào)用 Python 處理后返回結(jié)果,如 $res = ppython('test::go') 是調(diào)用test.py 中的 go 函數(shù),也可加上更多參數(shù),第二個參數(shù)起將為被調(diào)的函數(shù)傳遞更多參數(shù)。

php_python.py 是 PPython 啟動后直接運行的全局代碼,有全局配置或進程啟動后的通用處理都寫在這里,如原生代碼中建立了數(shù)據(jù)庫連接等,項目中應(yīng)視情況作優(yōu)化。

但 Python 令人感興趣的主要方面不只是像 PHP 那樣描述業(yè)務(wù)功能,它可以在人工智能等領(lǐng)域所需要的計算型任務(wù)提供對更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)的處理,因此二者的結(jié)合可以給 PHP 帶來更多應(yīng)用場景。

改進

此外,原生的 php_python.py 還有些不足。筆者用 ppython 調(diào)用自定義代碼中遇到了三個問題,并相應(yīng)做了解決:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2. 不支持 complex(復(fù)數(shù)類),復(fù)數(shù)是數(shù)學(xué)上的一種數(shù)據(jù)類型,主要包括 real(實部)和 imag(虛部)數(shù)據(jù),雖然日常生活中遇到較少,但 AI 和各種專業(yè)研究領(lǐng)域或并不罕見。Python 里有 complex 類,對復(fù)數(shù)可以直接進行各種計算,但 PPython 序列化和反序列化對 complex 沒有處理。為了能讓 complex 包括的數(shù)據(jù)能正常返回,只要在 process.pyz_encode() 方法中加上符合 PHP 要求的序列化處理,代碼如下:


    1. elif isinstance(p, numpy.complex128):

    2.    t1 = str(p.real)

    3.    t2 = str(p.imag)

    4.    return 'O:7:"complex":2:{s:4:"real";d:%s;s:4:"imag";d:%s;}' % (t1,t2)

  3. 不支持 ndarray(多維數(shù)組)。相比 complex,ndarray 要普通得多,相信凡使用到 Python 的各種計算功能,ndarray 是無法回避的,甚至 ndarray 在一定程度上成就了 Python。但原 php_python.py 不能識別 ndarray。不過解決起來并不難,在 process.py 里找到z_encode() 方法,加上下面這段,可以直接將 ndarray 轉(zhuǎn)化為符合 PHP 要求的數(shù)組(數(shù)字索引)。


    1.    elif isinstance(p, numpy.ndarray):

    2.        s = ''

    3.        i = 0

    4.        for d in p:

    5.            s += 'i:%d;%s' % (i,z_encode(d))

    6.            i += 1

    7.        return "a:%d:{%s}" % (len(p),s)

  4. 原代碼不太穩(wěn)健,如數(shù)據(jù)為 ndarray 類型,if p == None:報錯ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(),因為p == None的結(jié)果也是ndarray,不返回false ,將判斷方法改為if p is None:可避免出錯。

    相應(yīng)地 PHP 端也要注意一下序列化和反序列化的處理。

處理回復(fù)中類似 complex 這樣的對象數(shù)據(jù)時,如系統(tǒng)中沒有定義相應(yīng)的類,PHP 是可以反序列化的,但將顯示為 “incomplete object”,vardump 看得到 realimag 數(shù)據(jù),但不能直接操作,自行定義 complex 類后,則按指定的類進行解析,與 PHP 內(nèi)的一般對象無異,可以輕松進行所有操作。

至此,PHP 與 Python 的功能調(diào)訊已無問題。

補充:注冊為服務(wù)

命令行下啟動 php_python.py 主要是方便調(diào)試,可以看到觀察反饋信息等,生產(chǎn)環(huán)境中手工啟動 PPython 畢竟不太方便??梢詫?PPython 配置成服務(wù),修改端口也可以為不同的應(yīng)用配置不同的 PPython 端。

Linux 下將一個進程注冊為服務(wù)很簡單,只要建立 /usr/lib/systemd/system/ppython.service,內(nèi)容如下:

[Unit]Description=PHP-Python ServiceAfter=network.target remote-fs.target nss-lookup.target [Service]ExecStart={PPYTHON_PATH}/php_python.py [Install]WantedBy=multi-user.target

其中 {PPYTHON_PATH} 要改成實際路徑。

總結(jié)

有了 PPython,可以摒棄 exec() 這種 shell 調(diào)用,使開發(fā)回歸到邏輯本身。

到此,相信大家對“PPython的原理和架構(gòu)介紹”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI