介绍一个基于 .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 最新的项目模板:

Copydotnet new -i Peachpie.Templates::*

然后就会出现三个新的项目模板:Console Application、Class library 和 ASP.NET Core Empty。

我们这次整个 Console Application 看看。

Copydotnet new console -lang PHP

然后随便写点代码:

Copy<?phpfunction 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 运行!

编译输出(请无视掉我的霓虹语电脑环境):

Copy.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+565af85b9aafc42fe1af2f30ccd73ff093a2fad7PeachPieConsole -> C:\Users\hez20\source\repos\PeachPieConsole\bin\Debug\netcoreapp3.1\PeachPieConsole.dllビルドに成功しました。0 個の警告0 エラー経過時間 00:00:12.98

Voila!

输出:

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

如果去掉打错一个变量 $value 变成 $vuale 会怎么样呢?

Copy<?phpfunction 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();

编译输出:

Copy.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 不会报错而是给了警告。

但如果我们少一个分号呢:


<?phpfunction 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();

编译输出:

Copy.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>


<?phpfunction 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();

输出:

Copy0: 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.AspNetCore(https://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=398940public 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!

Copydotnet publish -c Release

最后打包 bin/Release/netcoreapp3.1/publish 上传到服务器上面,搭建好数据库然后运行即可。

完结撒花#

进入管理面板,大多数主题、插件都能正常工作,安装点主题,配置配置插件和 SMTP,就全部搞定啦。

内存占用 195 MB,运行在 .NET Core 3.1.3 上,非常清真!

至此我的 Blog 搭建完成,欢迎大家访问:https://hez2010.com 。

评论和注册什么的也开放了,欢迎大家常光临~

后续我也会不断在上面更新文章,当然,这个 Blog 上面的内容也就不仅限于编程啦,敬请期待~

从此 PHP 也是 .NET 上的一门语言了,完结撒花~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[设计模式]适配器模式

适配器模式:将一个类的接口转换成客户希望的另外一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 &#xff08;将已经写好的&#xff0c;但是不符合需求的接口&#xff0c;转换成目标接口&#xff09; 代码如下: #include <iostream>…

[工具]微软的学习平台Microsoft Learn很好用,推荐一下

1. 什么是Microsoft LearnMicrosoft Learn是微软这两年大力推广的全新学习平台&#xff0c;可提供 Microsoft 产品交互式学习体验。基本上无需登录即可使用&#xff0c;但登录后可以使用更多功能&#xff0c;包括&#xff1a;累积分数和成就跟踪学习活动进度使用免费的 Azure 资…

多终端数据同步机制设计

多终端数据同步机制设计之前写过一篇文章数据同步流程设计的文章&#xff0c;这里整理一下在公众号里分享一下Intro因为项目需要&#xff0c;需要设计一个多终端数据同步的机制&#xff0c; 需要满足以下条件&#xff1a;多个终端数据操作及同步&#xff0c;终端可能离线每次同…

Popular Cows POJ - 2186(tarjan算法)+详解

题意&#xff1a; 每一头牛的愿望就是变成一头最受欢迎的牛。现在有 N头牛&#xff0c;给你M对整数&#xff08;A,B&#xff09;&#xff0c;表示牛 A认为牛B受欢迎。这种关系是具有传递性的&#xff0c;如果 A认为 B受欢迎&#xff0c; B认为 C受欢迎&#xff0c;那么牛 A也认…

[设计模式]装饰模式

装饰模式: 通过AbstractEquipment装饰AbstractHero&#xff0c;使其heroA增加了一个穿装备的功能。 代码如下: #include <iostream> using namespace std;class AbstractHero {public:virtual void showStatus() 0;int hp;int mp;int at;int df; };class HeroA :publi…

ASP.NET Core分布式项目实战(Consent Controller Get请求逻辑实现)--学习笔记

任务20&#xff1a;Consent Controller Get请求逻辑实现接着上一节的思路&#xff0c;实现一下 ConsentController根据流程图在构造函数注入 IClientStore&#xff0c;IResourceStore&#xff0c;IIdentityServerInteractionService构造函数private readonly IClientStore _cli…

[设计模式]观察者模式

代码如下: #include <iostream> #include <list> using namespace std;class AbstractHero { public:virtual void update() 0; };class HeroA :public AbstractHero { public:HeroA(){cout << "英雄A正在打BOSS" << endl;}virtual void u…

RMQ算法讲解

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/qq_41311604/article/details/79900893 </div><!--一个博主专栏付费入口--><!--一个…

Kubernetes是容器化微服务的圣杯么?

导语Kubernetes已成为山丘之王。开源技术Kubernetes以及随后的发行版正以超快的速度让人们爱上容器技术&#xff0c;并且开始夺回对容器化环境的控制权。不幸的是&#xff0c;编排容器只是战斗进行了一半。正文云服务提供商接连宣布他们的编排选择是Kubernetes私有发行版&#…

[设计模式]命令模式

代码如下: #include <iostream> #include <queue> #include <Windows.h> using namespace std;class HandleClientProtocol { public:void addMoney(){cout << "给玩家增加金币" << endl;}void addDiamond(){cout << "给玩…

Zjnu Stadium HDU - 304 加权并查集

题意&#xff1a; 观众席围成一圈。列的总数是300&#xff0c;编号为1–300&#xff0c;顺时针计数&#xff0c;我们假设行的数量是无限的。将有N个人去那里。他对这些座位提出了要求&#xff1a;这意味着编号A的顺时针X距离坐着编号B。例如&#xff1a;A在第4列&#xff0c;X…

还不明白可空类型原理? 我可要挖到底了

一&#xff1a;背景1. 讲故事做好自媒体到现在有一个月了&#xff0c;关注我的兄弟应该知道我产出了不少文章&#xff0c;号里的粉丝也多起来了&#xff0c;我也尽最大努力做到有问必回&#xff0c;现在是基础的、高深的问题都接踵而来&#xff0c;可我也只是一只小菜鸟&#x…

[设计模式]策略模式

策略模式:定义了一系列算法&#xff0c;并将每一个算法封装起来&#xff0c;而且使它们还可以相互替换。 策略模式让算法独立于使用它的客户而独立变化。 代码如下: #include <iostream> using namespace std;class WeaponStrategy { public:virtual void useWeapon()…

[设计模式]模板方法模式

模板方法模式: 定义一个操作中算法的框架&#xff0c;而将一些步骤延迟到子类中。模仿方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 代码如下: #include <iostream> using namespace std;class DrinkTemplate { public:virtual void Boi…

差距(分享)

非985大学生, 你和别人的差距在哪里?&#xff08;转&#xff09; 非985大学生, 你和别人的差距在哪里? 中国青年报03-24 在知乎上看到这样一段话&#xff1a; “渣学校意味着渣教学&#xff0c;渣教学意味着渣学历&#xff0c;渣学历意味着渣就业&#xff0c;就算以后考了研究…

在微服务框架Demo.MicroServer中添加SkyWalking+SkyApm-dotnet分布式链路追踪系统

1.APM工具的选取Apm监测工具很多&#xff0c;这里选用网上比较火的一款Skywalking。Skywalking是一个应用性能监控(APM)系统&#xff0c;Skywalking分为服务端Oap、管理界面UI、以及嵌入到程序中的探针Agent部分&#xff0c;大概工作流程就是在程序中添加探针采集各种数据发送给…

计算机组成原理期末复习题

地址总线A15~Ao(低),存储空间(按字节编址)分配如下 2000H~3FFFH为ROM区, 5000H~6FFFH为RAM区。用 ROM芯片(4Kx4)和RAM芯片(4Kx4)组成该存储器。请回答 &#xff1a;(1)分别需要ROM和RAM多少片? (2)用二进制形式写出每组芯片的地址范围,并说明可以通过哪些地址位来形成片选信号…

干货分享:如何使用Kubernetes的Ingress API

导语以Kubernetes的Kong为例&#xff0c;聊聊当前流行的开源且与云无关的Ingress控制器。正文您可以通过使用诸如Kong for Kubernetes的Ingress控制器&#xff08;使用自定义资源定义并提供许多插件&#xff09;来极大地扩展Ingress资源的功能。Kubernetes正在整个技术行业中得…

计算机组成原理期末复习往年卷子

1. I/O设备的编址方式通常有___统一编址__和_独立编址__两种方式。P145 2&#xff0e;Cache是一种高速缓冲存储器&#xff0c;是为了解决____CPU____和___主存____之间速度不匹配而采用的一项重要技术。P124 3&#xff0e;在计算机系统中&#xff0c;I/O设备与主机传递消息的…

.NET Core接入ElasticSearch 7.5

写在前面最近一段时间&#xff0c;团队在升级ElasticSearch&#xff08;以下简称ES&#xff09;&#xff0c;从ES 2.2升级到ES 7.5。也是这段时间&#xff0c;我从零开始&#xff0c;逐步的了解了ES&#xff0c;中间也踩了不少坑&#xff0c;所以特地梳理和总结一下相关的技术点…