顯示廣告
隱藏 ✕
※ 本文為 dinos 轉寄自 ptt.cc 更新時間: 2016-12-09 17:16:15
看板 PHP
作者 Neisseria (Neisseria)
標題 [教學] 用 PHP-CPP 寫 PHP extension (1)
時間 Wed Dec  7 11:03:21 2016


如果 PHP 程式的速行速度無法滿足需求
將其改寫成 PHP extension 或許可以處理這個議題

傳統上,要寫 PHP extension 要用 C,而且要懂 Zend C API
說實在,還蠻費心力的

幸好有工程師開發了替代的方案,讓後人不需再和 Zend C API 奮戰
經 google 可知大致上有兩種方案:

1. Zephir:一個新的 PHP-like 編譯語言,寫完後程式碼可編譯成 PHP extension
   是由 Phalcon 團隊開發的,Phalcon 本身也有使用這個語言

2. PHP-CPP:一個 C++ 函式庫,加入特有的 PHP 相關物件

由於 PHP-CPP 的寫法,和原來的 C++ 略有不同,筆者將其視為一種 DSL
使用這個方案的好處在易於橋接外部 C/C++ 函式庫

預計會寫兩篇,這是第一篇


如果想直接研究程式碼,可到這個 repo
https://github.com/cwchentw/doubler-php-extension-demo
GitHub - cwchentw/doubler-php-extension-demo
[圖]
Contribute to doubler-php-extension-demo development by creating an account on GitHub. ...

 
接下來,筆者會提示要點


首先,要實作 doubler 這個 toy library
這個函式庫是用 Rust 撰寫,輸出成 C shared library
如果不想用 Rust,也可用其他語言,能輸出 C/C++ shared library 即可
目前這個 library 已完成


但是,Rust 不會自動生成 header,要自己撰寫
撰寫 header 時要注意,我們會輸出到 C++ 中
要用 extern "C" 避免 name mangling


#ifndef _DOUBLER_H_
#define _DOUBLER_H_

#ifdef __cplusplus
extern "C" {
#endif

  int double_int(int);
  double double_float(double);
  char* double_str(char*);
  void str_free(char*);

#ifdef __cplusplus
}
#endif

#endif // _DOUBLER_H_


接著,要到 PHP-CPP 官網下載 EmptyExtension 這個專案骨架,再自行修改
目前仍要手動改 Makefile,還沒有自動化的流程
這部分請板友參考小弟的 repo 自行修改


接著,實作 C++ 程式碼的部分
要注意的是,PHP-CPP 的撰寫方式,和一般的 C++ 程式碼略有不同
我們看一下實際的範例

#include <phpcpp.h>
#include <string>
#include "doubler.h"

using std::string;

class Doubler : public Php::Base
{
public:
  Doubler() = default;
  virtual ~Doubler() = default;

  static Php::Value int_number(Php::Parameters&);
  static Php::Value float_number(Php::Parameters&);
  static Php::Value str(Php::Parameters&);
};

Php::Value Doubler::int_number(Php::Parameters& params)
{
  return double_int((int32_t)params[0]);
}

Php::Value Doubler::float_number(Php::Parameters& params)
{
  return double_float((double)params[0]);
}

Php::Value Doubler::str(Php::Parameters& params)
{
  char* s = double_str((char*)params[0].rawValue());
  string output = string(s);
  str_free(s);
  return output;
}

由以上程式碼,可發現撰寫 PHP-CPP 專案時,使用了特別的 Php::Parameters 表示
PHP 參數,回傳值也是特別的 Php::Value。另外,非基本型別要另外釋放記憶體。

其實我們這個 library 沒有物件,都是 static method,用類別只是當成命名空間
PHP-CPP 也支援非物件的函式和 PHP 的命名空間,可自行參考官網的說明


最後,要輸出該物件到 PHP。以下的 get_module 函式是每個 PHP-CPP 專案都有的

extern "C" {
    PHPCPP_EXPORT void *get_module()
    {
        static Php::Extension extension("doubler", "1.0");

        // Put your library here
        Php::Class<Doubler> doubler("Doubler");
        doubler.method<&Doubler::int_number>("int_number", {
            Php::ByVal("x", Php::Type::Numeric)
          });
        doubler.method<&Doubler::float_number>("float_number", {
            Php::ByVal("x", Php::Type::Float)
          });
        doubler.method<&Doubler::str>("str", {
            Php::ByVal("x", Php::Type::String)
          });

        extension.add(std::move(doubler));

        return extension;
    }
}

撰寫完相關程式碼後,再編譯即可得到 PHP extension。


可以寫一個簡單的 PHP 程式呼叫此 extension

<?php
// main.php
echo Doubler::int_number(2), "\n";
echo Doubler::float_number(1.3), "\n";
echo Doubler::str("Hi"), "\n";


如果只是要測試,不想安裝 extension,可從命令列呼叫此 extension

$ php -dextension=pwd/doubler.so main.php


這個範例到這裡算是告一段落了
接下來,我們會用另一個範例繼續展示 PHP-CPP 的使用

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 125.227.36.80
※ 文章代碼(AID): #1OHtlzyQ (PHP)
※ 文章網址: https://www.ptt.cc/bbs/PHP/M.1481079805.A.F1A.html
xdraculax: 純推不下1F 12/07 13:00
shadowjohn: 離上一次寫extension是6年前作手寫輸入法...2F 12/07 13:04
locklose: 推3F 12/07 16:30

--
※ 看板: dinos 文章推薦值: 0 目前人氣: 0 累積人氣: 471 
作者 Neisseria 的最新發文:
  • +32 [問卦] 大家雙11都買了些什麼? - Gossiping 板
    作者: 111.249.46.37 (台灣) 2022-11-11 15:37:05
    安安。今天雙11 聽說雙11買東西會特別便宜 哥最近下訂了一批好便宜的 BND 聽說這東西好厲害的 放著就會長錢出來 大家雙11 都買了什麼?卦?
    58F 34推 2噓
  • +15 [新聞] 選情告急!民主黨不敢提經濟 - Gossiping 板
    作者: 111.249.1.168 (台灣) 2022-11-04 20:43:41
    美國期中選舉倒數最後一週,選情告急的民主黨全力衝刺,總統拜登與前總統歐巴馬,全 國輔選馬不停蹄,但超過半數選民最在乎的通膨經濟難題,民主黨卻絕口不提。對手共和 黨加緊猛攻,還傳出人氣不敗的前總統川普, …
    29F 15推
  • +27 [新聞] 程式語言Python受歡迎程度持續飆升 - Gossiping 板
    作者: 36.228.196.240 (台灣) 2022-08-10 18:10:05
    程式語言Python在熱門程式語言排行榜TIOBE Index中,目前制霸第一名且呈現勢不可擋 的成長趨勢,在本月又上漲2%,其市占達到15.42%的歷史新高,與去年同期相比成長了 3.56%。 TI …
    57F 30推 3噓
  • +42 [新聞] Google發表欲繼承C++的程式語言Carbon - Gossiping 板
    作者: 111.249.47.237 (台灣) 2022-07-22 18:42:44
    歷來不斷有新程式語言革新或試圖取代舊語言,像是Kotlin之於Java,或蘋果的Swift之 於Objective-C,以及微軟的TypeScript之於Javascript。Google本周在Cpp …
    84F 45推 3噓
  • +34 [問卦] 洗衣機的王者 - Gossiping 板
    作者: 114.25.211.178 (台灣) 2022-05-31 13:27:18
    各位年收入 300 萬的鄉民安安 電視機的王者是索尼 冷氣機的王者是日立 瓦斯爐的王者是櫻花 洗衣機的王者是?卦?
    70F 36推 2噓
點此顯示更多發文記錄
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇