介紹一個基於 .NET 的船新 PHP SDK + Runtime: PeachPie

来源:https://www.cnblogs.com/hez2010/archive/2020/05/12/12878619.html
-Advertisement-
Play Games

基於 .NET 的一個全新的、好用的 PHP SDK + Runtime: PeachPie 來啦! ...


前言

這幾天想基於 .NET Core 搞一個自己的博客網站,於是在網上搜刮各種博客引擎,找到了這些候選:Blogifier、Miniblog 以及 edi 寫的 Moonglade。

Blogifier:這是前端是個 Angular SPA 應用,不利於 SEO,同時首屏載入速度慢,因此排除。

Miniblog:顧名思義 Mini,可以完美承載內容但是主題實在是過於簡單,沒有可自定義性,因此排除。

Moonglade:總體感覺不錯,界面設計得也很好,功能全面,然而需要 SQL Server 作為資料庫,然而 SQL Server 雖然有 Linux 版本,但受限於主機配置和預算因此也被排除。

難道就沒有適合我需求的博客引擎了嗎?答案當然是:有。

眾所周知 PHP 是世界上最好的語言(滑稽),還是眾所周知有一個叫做 WordPress 的博客引擎生態非常龐大,而且是使用 PHP 構建的。

可是 PHP 和 .NET 又有什麼關係呢?

PeachPie

PeachPie 是一個完全構建於 .NET Standard 之上的一套完整的 PHP SDK + Runtime,包含編譯器和運行時等等,相容 PHP 5.4-7.4(當然部分功能仍在開發中)。

官網:https://www.peachpie.io

那麼 PeachPie 有什麼優點呢:

  • 開源:https://github.com/peachpiecompiler/peachpie
  • 跨平臺:因為 PeachPie 完全構建於 .NET 之上,因此也就跟著跨平臺了,Windows、MacOS、Linux 等等,從架構上跨 x86、x86_64、ARM、ARM64,未來甚至還會有 MIPS、MIPS64、Risc-V 等等......
  • 純托管代碼:藉助 VS 強大的調試器和 IDE 體驗,從開發、調試到測試、Profile 一條龍非常爽
  • 編譯:PHP 是沒有編譯之說的,這門動態類型語言和 Python 面臨一樣的問題,幾乎無法在編譯時發現代碼中的錯誤,即便藉助 linter 診斷出了語法錯誤也很難診斷出類型的錯誤。而 PeachPie 則有完善的編譯器套件將 PHP 代碼完整的編譯為 .NET Standard 程式集,意味著在編譯期就做好了語法和類型檢查,保證了運行時不會因為代碼問題導致程式崩潰,同時應用分發的時候也不需要源代碼,確保了源碼安全
  • 與 .NET 互操作:PeachPie 在保留了 PHP 原本的生態基礎上做到了 PHP 和 .NET 的互操作,一個 PeachPie 項目不但可以使用 PHP 原有生態中的包和插件,還能享受 .NET 的生態,快樂超級加倍
  • 運行在 .NET 上:CLR/CoreCLR 自帶久經考驗的 JIT 和 GC,因此通過 PeachPie 編譯的程式集運行在 CLR/CoreCLR 之上則無需做任何的代碼改動即可享受到這些東西,在 php-bench 中,藉助 CoreCLR 平臺的 JIT,函數調用性能拉開了原來 PHP 幾個數量級
  • .NET Foundation 項目:背後有 .NET Foundation 支持,瓦利亞高品質,有保證

可是有人就要問了,為什麼我不直接用 PHP 而是選用 PeachPie 曲線救國呢?

因為我樂意,雨女無瓜(逃

開始使用

本文開發環境採用 Visual Studio Code(需要安裝 PeachPie 插件),當然你也可以用 Visual Studio 等其他開發工具。

安裝 PeachPie 最新的項目模板:

dotnet new -i Peachpie.Templates::*

然後就會出現三個新的項目模板:Console Application、Class library 和 ASP.NET Core Empty。

我們這次整個 Console Application 看看。

dotnet new console -lang PHP

然後隨便寫點代碼:

<?php

function main()
{
    $students = 
        array(
            array("first_name" => "Joe", "score" => 83, "last_name" => "Smith"),
            array("first_name" => "Frank", "score" => 92, "last_name" => "Barbson"),
            array("first_name" => "Benji", "score" => 90, "last_name" => "Warner")   
        );
    
    foreach ($students as $value) {
        echo $value["first_name"], " ", $value["last_name"], "'s score is ", $value["score"], "\n";
    }
}

main();

用配置 .NET Core 項目的方式寫好 Visual Studio Code 需要的 tasks.json 和 launch.json,隨便下點斷點然後編譯 + F5 運行!

編譯輸出(請無視掉我的霓虹語電腦環境):

.NET Core 向け Microsoft (R) Build Engine バージョン 16.7.0-preview-20220-01+80e487bff
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  プレビュー版の .NET Core を使用しています。https://aka.ms/dotnet-core-preview をご覧ください
  PeachPie PHP Compiler version 0.9.981+565af85b9aafc42fe1af2f30ccd73ff093a2fad7
  PeachPieConsole -> C:\Users\hez20\source\repos\PeachPieConsole\bin\Debug\netcoreapp3.1\PeachPieConsole.dll

ビルドに成功しました。
    0 個の警告
    0 エラー

経過時間 00:00:12.98

Voila!

Debug

輸出:

Joe Smith's score is 83
Frank Barbson's score is 92
Benji Warner's score is 90

如果去掉打錯一個變數 $value 變成 $vuale 會怎麼樣呢?

<?php

function main()
{
    $students = 
        array(
            array("first_name" => "Joe", "score" => 83, "last_name" => "Smith"),
            array("first_name" => "Frank", "score" => 92, "last_name" => "Barbson"),
            array("first_name" => "Benji", "score" => 90, "last_name" => "Warner")   
        );
    
    foreach ($students as $value) {
        echo $vuale["first_name"], " ", $value["last_name"], "'s score is ", $value["score"], "\n";
    }
}

main();

編譯輸出:

.NET Core 向け Microsoft (R) Build Engine バージョン 16.7.0-preview-20220-01+80e487bff
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  プレビュー版の .NET Core を使用しています。https://aka.ms/dotnet-core-preview をご覧ください
  PeachPie PHP Compiler version 0.9.981+565af85b9aafc42fe1af2f30ccd73ff093a2fad7
program.php(13,14): warning PHP5007: Undefined variable: $vuale [C:\Users\hez20\source\repos\PeachPieConsole\PeachPieConsole.msbuildproj] 
  PeachPieConsole -> C:\Users\hez20\source\repos\PeachPieConsole\bin\Debug\netcoreapp3.1\PeachPieConsole.dll

ビルドに成功しました。

program.php(13,14): warning PHP5007: Undefined variable: $vuale [C:\Users\hez20\source\repos\PeachPieConsole\PeachPieConsole.msbuildproj] 
    1 個の警告
    0 エラー

経過時間 00:00:09.51

由於上述代碼在 PHP 中是合法代碼,因此為了保持相容性,PeachPie 不會報錯而是給了警告。

但如果我們少一個分號呢:

<?php

function main()
{
    $students = 
        array(
            array("first_name" => "Joe", "score" => 83, "last_name" => "Smith"),
            array("first_name" => "Frank", "score" => 92, "last_name" => "Barbson"),
            array("first_name" => "Benji", "score" => 90, "last_name" => "Warner")   
        )
    
    foreach ($students as $value) {
        echo $value["first_name"], " ", $value["last_name"], "'s score is ", $value["score"], "\n";
    }
}

main();

編譯輸出:

.NET Core 向け Microsoft (R) Build Engine バージョン 16.7.0-preview-20220-01+80e487bff
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  プレビュー版の .NET Core を使用しています。https://aka.ms/dotnet-core-preview をご覧ください
  PeachPie PHP Compiler version 0.9.981+565af85b9aafc42fe1af2f30ccd73ff093a2fad7
program.php(12,5): error PHP2014: Syntax error: unexpected token 'foreach' [C:\Users\hez20\source\repos\PeachPieConsole\PeachPieConsole.msbuildproj]

ビルドに失敗しました。

program.php(12,5): error PHP2014: Syntax error: unexpected token 'foreach' [C:\Users\hez20\source\repos\PeachPieConsole\PeachPieConsole.msbuildproj]
    0 個の警告
    1 エラー

経過時間 00:00:01.77

這次就會直接報錯了。

由此可見,使用 PeachPie 能夠無需第三方工具輔助,直接在編譯時就驗證代碼正確性,對項目的健壯性有很大幫助。

PHP 與 .NET 互操作

我們試試互操作,在 PHP 裡面創建一個 .NET 中的 HashSet<TValue>

<?php

function main()
{
    $list = new System\Collections\Generic\HashSet<string>;
    $list->Add("test");
    $list->Add("hello");
    $list->Add("hello");
    $list->Add("lol");
    foreach ($list as $key => $value) {
        echo $key, ": ", $value, "\n";
    }
}

main();

輸出:

0: test
1: hello
2: lol

完美,另外,鑒於 PHP 代碼最後都會被編譯成 .NET Standard 程式集,因此反過來當然也沒問題,就不做介紹了。

一些坑

PeachPie 已經發展了好幾年的時間了,儘管大多數 PHP 代碼都能正常運行,但是標準庫仍存在一些相容性問題,具體可以去這裡跟蹤:https://docs.peachpie.io/compatibility-status

由於目前還在補全相容性問題,所以很多優化工作(比如數組的優化)都沒有做,性能方面還有很大的提升空間。

不過官方目前開發進度十分快,因此短時間內就能看到大量的新庫函數被實現,到目前已經是 0.9.800,1.0 正式版也快要發佈了,很快就能正式投入生產使用啦。

Blog 搭建

回到前面的主題,有了 PeachPie,我就能把 WordPress 放到 .NET Core 上面跑啦。

當然,直接下載下來 WordPress 的源代碼編譯跑到 ASP.NET Core 上面時會出現一些問題,比如資源載入全部 404,這是因為 PeachPie 在編譯 PHP 代碼時預設不會將非 .php 的文件包含到編譯過程中,我們需要修改 .msbuildproj 調整項目屬性將資源文件包含在編譯過程中,並作為 Content 引入。

另外由於 WordPress 首次配置會現場生成一個 config.php 文件,但是由於該文件是編譯後的程式集在運行時生成的,未參與編譯過程,因此運行時是找不到這個類的,除非重新編譯一遍。因此我們想採用更清真的方式,直接在 appsettings.json 裡面寫入配置然後運行時讀入代替原來的 config.php。

總之需要經過一系列操作,並且編寫少量代碼。不過,PeachPie 已經幫我們做好了這一切:iolevel 提供了一個即插即用的 WordPress 包 PeachPied.WordPress.AspNetCorehttps://github.com/iolevel/wpdotnet-sdk ),可直接作為 ASP.NET Core 中間件使用,非常方便。

那麼事情就簡單了:

dotnet new web
dotnet add package PeachPied.WordPress.AspNetCore --version 1.0.0-*

然後編寫少量服務端代碼,配置一下 https 跳轉、響應壓縮和靜態文件什麼的,再加入 WordPress 中間件:

Startup.cs

using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace KeBlogs
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddResponseCompression(options =>
            {
                options.Providers.Add<BrotliCompressionProvider>();
                options.Providers.Add<GzipCompressionProvider>();
                options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] {
                    "image/svg+xml",
                    "image/png",
                    "font/woff",
                    "font/woff2",
                    "font/ttf",
                    "font/eof",
                    "image/x-icon",
                    "application/json",
                    "application/octet-stream" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseHttpsRedirection();
            app.UseResponseCompression();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseWordPress();
        }
    }
}

代碼部分搞定,當然上述代碼你也可以用 PHP 來寫。

然後在 appsettings.json 寫入自己的配置,比如(SALT 部分可以沒有):

{
  "WordPress": {
    "dbhost":        "localhost",
    "dbpassword":    "password",
    "dbuser":        "root",
    "dbname":        "wordpress",
    "dbTablePrefix": "wp_",
    "SALT": {
      "AUTH_KEY":         "r(EoMbKEvlg){+!T42fh-e+~IGj-4q}g8HHB9hjbiC0J*ySU1Y*3z[3c}F;6=TA5",
      "AUTH_SALT":        "q0#AzvJ*[4~Bexa9*M(sC_#pDuGQBdjL1}j*RilSe0ku]P~KuTir[7PxjE:4)_zR",
      "LOGGED_IN_KEY":    "!AAienFSridCUzF(v}m#}_;+t%Rclg;mOPKwe;w7dN0M{d,]?8V+TRW_UG)tSswa",
      "LOGGED_IN_SALT":   "C=(4(8WPMeRu_h?g7!ddI*P:+SYU=3C%g)92oV}-y5tE0r?DHWl!fjPOp=bjx2YJ",
      "NONCE_KEY":        "Z[e37@=y)m.CHa:OSldh#RT@nIZxKYGwu!/hd:vK#^{_Ec7e{KNb(G.8ch/MkH(d",
      "NONCE_SALT":       ";v7Wv/BV)Pz{W,FaAKC0buH*5U4:g]qn~;b94x]f8=lm6!yyYSbW5*2y*kRXXEF5",
      "SECURE_AUTH_KEY":  "pc}_Pv52,m=j9l#llSkLVQib.Zm!;9FRzg:{(G]tM8}[}]pPDwB4k{xV+!e)9lmR",
      "SECURE_AUTH_SALT": "#n]+o^w/%-~MVzf{AUuxUAwF[n03r{kr^r1V?wqQ?Vjt}!0HSkCB-):u-ra1%tB="
    },
    "constants": {
    }
  }
}

然後發佈我們的 WordPress!

dotnet publish -c Release

最後打包 bin/Release/netcoreapp3.1/publish 上傳到伺服器上面,搭建好資料庫然後運行即可。

完結撒花

進入管理面板,大多數主題、插件都能正常工作,安裝點主題,配置配置插件和 SMTP,就全部搞定啦。

Admin

記憶體占用 195 MB,運行在 .NET Core 3.1.3 上,非常清真!

至此我的 Blog 搭建完成,歡迎大家訪問:https://hez2010.com

評論和註冊什麼的也開放了,歡迎大家常光臨~

後續我也會不斷在上面更新文章,當然,這個 Blog 上面的內容也就不僅限於編程啦,敬請期待~

Blog

從此 PHP 也是 .NET 上的一門語言了,完結撒花~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Go 語言是一種靜態類型的編程語言。這意味著,編譯器需要在編譯時知曉程式里每個值的類型。數據類型的出現是為了把數據分成所需記憶體大小不同的數據,編程的時候需要用大數據的時候才需要申請大記憶體,就可以充分利用記憶體。 Go語言內置以下這些基礎類型: 布爾類型:bool 整型:int8、byte、int16、 ...
  • 1、首先準備好數據。這裡的數據不是直接從資料庫中查到的數據而是將查到的數據複製一份,兩者的數據互不影響,這樣有利於複製之後的數據可以修改。 ① 定義一個從資料庫中查到的數據的方法(service層的實現類方法),這裡省略mapper映射文件和dao層介面的方法 /** * 參數是實體類,根據參數條件 ...
  • 安裝docker 1.更新yum包 yum update 2.卸載舊版本 yum remove docker 3.安裝依賴 yum install -y yum-utils device-mapper-persistent-data lvm2 4.設置yum源 yum-config-manager ...
  • 本博客系列是學習併發編程過程中的記錄總結。由於文章比較多,寫的時間也比較散,所以我整理了個目錄貼(傳送門),方便查閱。 "併發編程系列博客傳送門" 本文是轉載問斬,原文請見 "這裡" 一、Exchanger簡介 Exchanger——交換器,是JDK1.5時引入的一個同步器,從字面上就可以看出,這個 ...
  • 1.Xpath Helper Xpath Helper 是一個面向 Xpath 初學者的 Google Chrome 插件。相對於人工找 Xpath 語法,Xpath Helper 可以實現自動分析。只要你打開一個網頁,然後點擊任何一個網路元素,Xpath Helper 就能自動幫你找出相應的 Xp ...
  • 工作的時候,尤其是自媒體,我們必備水印添加工具以保護我們的知識產權,網上有許多的線上 / 下載的水印添加工具,但他們或多或少都存在以下問題: 線上工具需要上傳到對方伺服器,信息不安全。 很多工具不具備批量處理功能。 很多工具自定義的功能太少,如水印透明度,字體等。 操作繁瑣。這裡還要註意:光理論是不 ...
  • Attribute(特性)的概念不在此贅述了,相信有點.NET基礎的開發人員都明白,用過Attribute的人也不在少數,畢竟很多框架都提供自定義的屬性,類似於Newtonsoft.JSON中JsonProperty、JsonIgnore等 自定義特性 .NET 框架允許創建自定義特性,用於存儲聲明 ...
  • 隨著 .NET 5 發佈日期的日益臨近,其對應的 C# 新版本已確定為 C# 9.0,其中新增加的特性(或語法糖)也已基本鎖定,本系列文章將向大家展示它們。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...