介绍一个基于 .NET 的船新 PHP SDK + Runtime: PeachPie
介绍一个基于 .NET 的船新 PHP SDK + Runtime: PeachPie
前言#
这几天想基于 .NET Core 搞一个自己的博客网站,于是在网上搜刮各种博客引擎,找到了这些候选:Blogifier、Miniblog 以及 edi 写的 Moonglate。
Blogifier:这是前端是个 Angular SPA 应用,不利于 SEO,同时首屏加载速度慢,因此排除。
Miniblog:顾名思义 Mini,可以完美承载内容但是主题实在是过于简单,没有可自定义性,因此排除。
Moonglate:总体感觉不错,界面设计得也很好,功能全面,然而需要 SQL Server 作为数据库,然而 SQL Server 虽然有 Linux 版本,但受限于主机配置和预算因此也被排除。
难道就没有适合我需求的博客引擎了吗?答案当然是:有。
众所周知 PHP 是世界上最好的语言(滑稽),还是众所周知有一个叫做 WordPress 的博客引擎生态非常庞大,而且是使用 PHP 构建的。
可是 PHP 和 .NET 又有什么关系呢?
PeachPie#
PeachPie 是一个完全构建于 .NET Standard 之上的一套完整的 PHP SDK + Runtime,包含编译器和运行时等等,兼容 PHP 5.4-7.4(当然部分功能仍在开发中)。
那么 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 最新的项目模板:
Copy
dotnet new -i Peachpie.Templates::*
然后就会出现三个新的项目模板:Console Application、Class library 和 ASP.NET Core Empty。
我们这次整个 Console Application 看看。
Copy
dotnet new console -lang PHP
然后随便写点代码:
Copy
<?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 运行!
编译输出(请无视掉我的霓虹语电脑环境):
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
PeachPieConsole -> C:Usershez20sourcereposPeachPieConsolebinDebugnetcoreapp3.1PeachPieConsole.dll
ビルドに成功しました。
0 個の警告 0 エラー
経過時間 00:00:12.98
Voila!
输出:
Copy
Joe Smith's score is 83
Frank Barbson's score is 92
Benji Warner's score is 90
如果去掉打错一个变量 $value 变成 $vuale 会怎么样呢?
Copy
<?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();
编译输出:
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:Usershez20sourcereposPeachPieConsolePeachPieConsole.msbuildproj]
PeachPieConsole -> C:Usershez20sourcereposPeachPieConsolebinDebugnetcoreapp3.1PeachPieConsole.dll
ビルドに成功しました。
program.php(13,14): warning PHP5007: Undefined variable: $vuale [C:Usershez20sourcereposPeachPieConsolePeachPieConsole.msbuildproj]
1 個の警告 0 エラー
経過時間 00:00:09.51
由于上述代码在 PHP 中是合法代码,因此为了保持兼容性,PeachPie 不会报错而是给了警告。
但如果我们少一个分号呢:
Copy
<?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();
编译输出:
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:Usershez20sourcereposPeachPieConsolePeachPieConsole.msbuildproj]
ビルドに失敗しました。
program.php(12,5): error PHP2014: Syntax error: unexpected token 'foreach' [C:Usershez20sourcereposPeachPieConsolePeachPieConsole.msbuildproj]
0 個の警告 1 エラー
経過時間 00:00:01.77
这次就会直接报错了。
由此可见,使用 PeachPie 能够无需第三方工具辅助,直接在编译时就验证代码正确性,对项目的健壮性有很大帮助。
PHP 与 .NET 互操作#
我们试试互操作,在 PHP 里面创建一个 .NET 中的 HashSet:
Copy
<?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();
输出:
Copy
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.AspNetCore(https://github.com/iolevel/wpdotnet-sdk ),可直接作为 ASP.NET Core 中间件使用,非常方便。
那么事情就简单了:
Copy
dotnet new web
dotnet add package PeachPied.WordPress.AspNetCore --version 1.0.0-*
然后编写少量服务端代码,配置一下 https 跳转、响应压缩和静态文件什么的,再加入 WordPress 中间件:
Startup.cs
Copy
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 部分可以没有):
Copy
{
"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!
Copy
dotnet publish -c Release
最后打包 bin/Release/netcoreapp3.1/publish 上传到服务器上面,搭建好数据库然后运行即可。
完结撒花#
进入管理面板,大多数主题、插件都能正常工作,安装点主题,配置配置插件和 SMTP,就全部搞定啦。
内存占用 195 MB,运行在 .NET Core 3.1.3 上,非常清真!
至此我的 Blog 搭建完成,欢迎大家访问:https://hez2010.com 。
评论和注册什么的也开放了,欢迎大家常光临~
后续我也会不断在上面更新文章,当然,这个 Blog 上面的内容也就不仅限于编程啦,敬请期待~
完结撒花~
作者: hez2010
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
web前端开发入门全套学习方法路径,兼职在家做网站也能月入上万!
前端学习路径 1.WEB前端快速入门 在本阶段,我们需要掌握 HTML 与 CSS 基础,当然,也包含 H5 和 C3 的新特性。这个部分内容非常简单,而且非常容易掌握。相信你也更愿意学习这个部分,毕竟他可以让你最直观的感受到前端的魅力。为了锻炼大家写代码,可以根据你喜欢的站点去实现效果。这一阶段是非常重要的基础阶段,所谓基础就是可能这个阶段我们的学习的内容,可以让我们开发出来绚丽网站站点,但是功能丰富却暂时做不到。 为了完成更绚丽的站点,我们需要掌握常见特效的实现,利用 css3 和 h5 的新特性实现动画,布局,雪碧图,滑动门,tab 切换等特效。并且掌握基础的站点优化内容。例如 sprite 等。虽然我们还不能完成更多交互内容,但是我们会学习到很多的知识模型和理论,而这些知识模型和理论是我们后期工作和学习的基石。扎实的基础有了,我们才能走的更稳更快。 注:本阶段不涉及到编程,主要是熟悉 HTML5 各种标签用法、CSS3 各种属性的用法。 2.JavaScript 基础与深入解析 JavaScript 语言非常重要,可以说学习前端本质就是学习“JavaScript”编程。后面学全...
- 下一篇
你应该知道的Python3.6、3.7、3.8新特性
你应该知道的Python3.6、3.7、3.8新特性 很多人在学习了基本的Python语言知识后,就转入应用阶段了,后期很少对语言本身的新变化、新内容进行跟踪学习和知识更新,甚至连已经发布了好几年的Python3.6的新特性都缺乏了解。 本文列举了Python3.6、3.7、3.8三个版本的新特性,学习它们有助于提高对Python的了解,跟上最新的潮流。 一、Python3.6新特性1、新的格式化字符串方式新的格式化字符串方式,即在普通字符串前添加f或F前缀,其效果类似于str.format()。比如 name = "red"print(f"He said his name is {name}.") 'He said his name is red.' 相当于: print("He said his name is {name}.".format(**locals()))此外,此特性还支持嵌套字段,比如: import decimalwidth = 10precision = 4value = decimal.Decimal("12.34567")print(f"result: {va...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS关闭SELinux安全模块
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音