如玫瑰一般的PHP与C#混合编程

故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的环境显得有点高射炮打蚊子(况且还有其他不可预见的阻力)。或许有读者会提出“抗议”:不是PHP写的么,直接看源码翻译出一份C#版的不就行了?然而事实并不如想象的美好,总之就是短期内无法这么做了。

如今的C#已经非常强大了,它除了可以做我们普通的站点开发、桌面开发和原生的Windows Phone、应用商店开发,还可以做其他诸如IOS、安卓开发;也通过用CLR来托起一个JVM(这里指IKVM.NET)来跑Java应用程序,当然也可以通过把PHP编译成IL来跑PHP的网站程序了。

本篇中,我们就如何进行PHP与C#混合编程作如下讨论:

  (1)、PHP与C#的胶水:“Phalanger”

  (2)、牛刀小试跑跑PHP

  (3)、如何添加PHP类库

  (4)、C#与PHP混合互调

  (5)、美丽如玫瑰,采摘须谨慎

本文中的示例代码请点击这里进行下载。



1、什么是Phalanger

什么事Phalanger,最简单的概括就是,它能够把PHP编译成DLL供我们C#调用。

Phalanger的官网是:http://www.php-compiler.net/

我们要做混合编程,首先得先从官网那里下载一个安装包。

下载下来之后,打开压缩包,双击Setup开始安装。

把这些都给安装了,前面两个必装,最后一个是模板文件,不想装就不装,已经安装的话它会写着“Already installed”。由图中,我们可以得知一个信息,那就是它只支持Framework 4.0。

把上面的东西安装好之后,我们需要的“胶水”就得到了。

2、在.NET里面跑一个php

嗯,phpinfo(),我没有猜出,这个函数应该是各位读者们第一个敲的,也是搭建完PHP环境之后必敲写的一个函数。我们也牛刀小试一番,试试执行这个函数。

我们先创建一个空的WebApplication

然后添加一个PHP文件,由于我们没有直接的PHP文件添加,所以我们随便添加了一个内容少一点的文件,然后改它的后缀为php并删光里面的代码。

写上我们的代码(还带有智能提示,先进!!!):

然后按下“F5”

 然后就奇迹般的出现了我们想要的页面。

3、添加PHP的类库

事实上,即使我们是写原生的PHP,我们都需要使用到大量的PHP库,譬如MySQL库、GD库、CURL库等。在这里当然也不例外,我们也需要使用那些库。不过在这里,我们所使用的库并不是PHP/ext中的那些库,而是Phalanger给我们准备好的库,它们随着Phalanger的安装一同安装到我们的电脑当中,有兴趣的读者可以翻开GAC目录,里面会多了很多php打头的文件夹,那些就是与Phalanger相关的库了。

需要使用哪个库,就自行的在WebConfig的phpNet节点下添加,譬如我需要用MySQL的库,则在WebConfig这样配置

<?xml version="1.0" encoding="utf-8"?>

<!--
  有关如何配置 ASP.NET 应用程序的详细消息,请访问
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <phpNet>
    <classLibrary>
      <add assembly="PhpNetMySql, Version=3.0.0.0, Culture=neutral, PublicKeyToken=2771987119c16a03" section="mysql"/>
    </classLibrary>
  </phpNet>

</configuration>

Web.Config

这里注意一点,MYSQL的扩展库请使用CodePlex上的,而非自带的,自带的版本链接高板MYSQL可能会遇到问题(地址如下:http://phalangermysql.codeplex.com/releases/view/103022

这里还有另外一点需要注意,CodePlex上的扩展下载下来之后是这样的。

MySql的库命名有问题,正确的应该是“MySql.Data.dll”,各位读者请留意。

然后就是写下我们读取数据库信息的代码:

<?php
/***** 判断库是否被加载 *****/
$extensionName="mysql";
if(!extension_loaded($extensionName)){
    echo $extensionName.‘没有被加载进来‘;
    exit;
}

/**** 操作mysql ****/
$host="192.168.70.128";
$name="root";
$pwd="root";

$conn=mysql_connect($host,$name,$pwd) or die("mysql数据库连接失败");
mysql_select_db("phalangerdb",$conn)or die("无法选择数据库");
mysql_query("set names utf8");
$sqlstr="select * from person";
$result = mysql_query($sqlstr);
echo ‘<pre>‘;
while($row=mysql_fetch_row($result)){
    print_r($row);
}
echo ‘</pre>‘;

mysql_free_result($result);
mysql_close($conn);

mysqlextension.php

然后运行并查看结果:

它成功的读取到我们数据库的东西并输出到页面中。

4、C#与PHP互调

既然是混合编程,如果没有两种语言之间的相互调用那又如何能够称得上混合编程呢?本节中,我们主要分两个部分,其一就是PHP调C#函数,其二就是C#掉PHP函数。

PHP调用C#,Phalanger官网中主要的范例均是此,这里就不作讲解了,有需要的读者可移步到Phalanger官网中看里面的Blog。本文中讲解的是使用概率更高同时也是官网中比较缺乏资料的C#调用PHP的函数。

首先我们先创建一个PHP的函数:

<?php
function Sum($a,$b){
    return $a+$b;
}

function SayHello(){
    return ‘Hello,我是小蝶惊鸿‘;
}

Fun.php

然后新建一个WebForm页面程序,并在CodeBehind中调用它(这里是简单加法例子):

namespace PhalangerDemo.demo3
{
    using System;
    public partial class WebForm1 : System.Web.UI.Page
    {
        private PHP.Core.ScriptContext phpContext;

        public WebForm1()
        {
            phpContext = PHP.Core.ScriptContext.CurrentContext;
            phpContext.Include("Fun.php", true);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            var context = phpContext.Call("SayHello", new object[] { }).ToString();
            Response.Write(context.StartsWith("&") ? context.Substring(1) : context);
        }

        protected void btnAdd_Click(object sender, EventArgs e)
        {
            var num1 = txtNum1.Text as object;
            var num2 = txtNum2.Text as object;
            var result = phpContext.Call("Sum", new object[] { num1, num2 }).ToString();
            txtRes.Text = result.StartsWith("&") ? result.Substring(1) : result;
        }
    }
}

然后再页面中运行看看,Cool:

这里,我要对CodeBehind(C#)部分的代码进行下讲解,它的原理大概如下:

  (1)、先获取PHP的上下文对象PHPContext

  (2)、然后往PHPContext中require_once我们写的“Fun.php”

  (3)、通过Call方法,第一个参数传入方法名,第二个参数传入Object数组类型的参数。调用PHP中的函数

  (4)、在被调用的PHP函数执行完成之后,将它的返回接收回来。并过滤开头的“&”字符。

至于更深入的,譬如如何New一个PHP的Class之类的,我没有进行深入的研究,所以这里就不作描述,有兴趣的读者可以自行深入研究,同时也欢迎有此经验的读者进行分享。

5、这美丽又丑陋的Phalanger

在前面的几章中,Phalanger的表现是如此的美丽优秀,它好比一朵玫瑰,看起来是那么的鲜艳,闻起来是那么的幽香,但是当你想采摘它的时候,手中拿着的确是幽艳玫瑰之下的荆棘。也只有你划破伤口流着血的时候,你才感觉到原来采摘这朵玫瑰是那么的痛。

我把开篇时的故事继续说完,到了这一步,读者们大概也可以猜到是个什么情况了,没错,我的尝试失败了,这个PHP的组件无法正常的运行。

下面,我给各位读者分享两个这个组件所遇到致命性伤痕:

  (1)、if中对byte的真假识别不一致。

  同样是读取一个文件,通过if(byte[])来判断这个文件是否为空,原生的PHP中可以根据传入的byte[]是否为null来决定true/false,而Phalanger则无论如何一直返回false。

  (2)、同样的PHP内置函数,执行的效果却不一致。

  这里的所说的函数运行效果不一致并不是说效果完全的不一致,普通的使用还是没有问题的(正如我刚才读取mysql那样),而是有极少数的函数在特殊的条件下运行后得出的结果在原生PHP与Phalanger中是不一样的。



当然了,一百个读者有一百个海姆莱特,萝卜青菜各有所爱,Phalanger到底值不值得使用,应该怎么使用,还是全凭各位读者自己博弈了。

  

如玫瑰一般的PHP与C#混合编程

时间: 2024-08-01 01:42:43

如玫瑰一般的PHP与C#混合编程的相关文章

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作

Matlab C混合编程

由于看的代码里面以及一些工程需要涉及一些Matlab 混合编程,一直想看一下,首先一个就是使用C编写代码,编译之后由Matlab调用,这需要用到Mex函数,mex程序就是根据一定的接口规范(mtlab提出的)编写的一个dll,Mex文件既可以用c,也可以用fortran来编.本文介绍的是用C编写的. 这样做,若是代码中有循环的话,使用matlab的话需要循环解释多次,而使用C语言编译成dll之后,首先可以将循环体放入二进制程序中,利用matlab加快运算,而不是循环解释执行matlab代码.还有

C++与Java混合编程

http://www.cnblogs.com/lxshanye/p/3209542.html 现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子,一个软件为了快速开发,可能是使用Delphi或VB作为界面开发首选语言,底层的指令或核心算法,会使用C/C++处理,涉及数据处理的时候,为了安全和快速开发,会使用Javascript或Python等脚本语言实现数据分析处理.因此,开发者应该学习或掌握语言混合编程. C

【5.1送礼】国内第一部Matlab和C#.Net混合编程入门级视频教程【完全免费】

上一次写博客很久了,一直在忙彩票分析系统架构的事情,写博客真是件费神的事情,非常花时间.今天抽空发布这篇博客,是为了开源一部自己录制的视频教程-Matlab和C#.Net混合编程视频教程[入门级].下面说说这部视频教程的来由和一些事情,想获取的仔细看看,别忘了点[推荐]哦! 一.为啥要开源 1.1 视频的来源 这部视频教程是在2012年年底闲时比较多,当初也是很多朋友,网友提出这个Matlab.Net混合编程入门比较难,没有资料,所有就特意录制了一部比较简单的视频教程.并有条件的对广大网友免费开

Qt Quick 之 QML 与 C++ 混合编程详解

Qt Quick 技术的引入,使得你能够快速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ,多线程,又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等,在 QML 中要么不可用,要么用起来不方便,所以呢,很多时候我们是会基于这样的原则来混合使用 QML 和 C++: QML 构建界面, C++ 实现非界面的业务逻辑和复杂运算. 请给

extern &quot;C&quot; 的含义:????实现C++与C及其它语言的混合编程

C++中extern "C"的设立动机是实现C++与C及其它语言的混合编程. C++为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同.对于函数void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字. extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本

Matlab.NET混合编程调用Figure窗体

原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用Matlab函数这方面,积累了比较多的经验,和使用经验密切相关.根据很多朋友经常遇到的WinForm窗体混编调用Matlab的Figure的问题,花了一些功夫,把这个封装为C#控件,使得大家可以很容易调用Matlab的Figure了. 2.Matlab.NET混合编程概述 这方面就不仔细阐述了,主要是

[转] Matlab与C++混合编程,添加OpenCV库

原文地址 峰回璐转 最近在做运动医学软件优化工作,此款软件框架及算法语言全由matlab实现,虽然matlab矩阵运算.数值计算能力强大,但速度让人难以忍 受.软件立刻移植到C++上又不太实际,故采用联合编程的方式,速度难以容忍的算法交给C++实现,C++在实现代码的过程中某些数值计算及图像处理算法 调opencv库函数. 在网上有很多matlab编写mex函数调用opencv库的方法,但都不能直接拿来.经过一步步试验,修改,最终完成,现将过程及内容记录下来留给后来人参考. 第一步: (参考参考

C#和matlab混合编程

C#和MatLab的混合编程,充分利用了winform的直观显示和matlab的强大计算能力.在此以一个小例子的形式给大家讲述一下二者混合编程的实现. 一.软件的配置说明 C#版本:VS2010        matlab版本:matlab2013a 二.把 matlab函数编译成dll文件 2.1首先写一个函数的.m文件(如下函数MatrixOpera实现两个矩阵的相加和相减) %--------------------------------------------------------