将PHP类转换为C#类?

5
我在一家使用C#开发应用程序的公司工作。最近我们接到一个客户的要求,希望我们重新构建一个用PHP编写的应用程序。这个应用程序接收汽车上安装的盒子传来的GPS数据,并将其处理成可用信息。
GPS设备制造商提供了一个PHP类,用于解析接收到的信息并提取坐标。我们考虑将PHP类重写为C#类,以便我们可以使用它并进行适应。但是,在制造商的网站上,有一行文字让我感到不安:
“传输数据的编码格式和内容会不断变化。这是由于新模块固件版本实现了其他功能,从而几乎不可能对其进行文档化,也无法自己正确解码。”
因此,我现在正在寻找一种方法来使用“不断变化”的PHP类并在C#中访问它。类似于仅公开我需要的一些函数的外壳。但我不知道如何做到这一点。有谁能帮我找到解决方案吗?

有人可能会问,什么样的疯狂GPS设备制造商不提供标准接口给他们的设备,因为已经有一些明确定义的接口(例如NMEA)。 - Alistair Evans
告诉我吧。我非常讨厌不得不使用某种hacky解决方案来“与”这些设备交流。但是我能做什么呢?我不能因为我不喜欢这种语言就改变他们整个公司的流程。 - Duncan Roosma
6个回答

3

我知道这是一个非常粗糙的解决方案,但如果你需要一些 PHP 代码,而不想每次都重复移植到 C# 中,可以尝试以下方法,尽管这意味着你需要在目标机器上安装 PHP 命令行工具。

第一步是编写一个 PHP 脚本,不断从 stdin 读取数据,使用供应商提供的特殊类进行解码,并将结果写入 stdout。下面是一个非常简单的示例:

<?php

include("VendorDecodingClass.php");

while(true) 
{
    $input = fgets(STDIN); //read off of the stdin stream

    //can't remember if this is valid, but somehow check that there is some data
    if($input) 
    {
         //pass it off to the vendor decoding class
         $output = VendorDecoding::decode($input);    

         fwrite(STDOUT, $output); //write the results back out
    }
    //sleep here so you don't suck up CPU like crazy 
    //(1 second may be a bit long tho, may want usleep)
    //Edit: From Tom Haigh, fgets will block, so the sleep isn't necessary
    //sleep(1); 
}

?>

无论如何,一旦您安装了该软件包,在C#应用程序中,在开始时创建一个新的进程来运行该脚本,然后将Process实例保存在某个地方,以便稍后可以引用STDIN和STDOUT。示例:

ProcessStartInfo procStartInfo = new ProcessStartInfo("php", "yourscript.php");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;

Process proc = new Process(); //store this variable somewhere
proc.StartInfo = procStartInfo;
proc.Start();

当您想要解码数据时,只需向您创建的php进程的stdin写入,并在stdout上等待响应。使用stdin / stdout方法比每次想要解码一些数据时创建新进程更有效,因为创建该进程的开销可能会很明显。

proc.StandardInput.WriteLine(somedata); //somedata is whatever you want to decode

//may need to wait here, or perhaps catch an exception on the next line?

String result = proc.StandardOutput.ReadLine();

//now result should contain the result of the decoding process

免责声明,我没有测试过这些代码,但那是我可能会使用的一般要点。

我还想到了另外一件事,你需要一些机制来终止PHP进程。也许使用Process.Kill可以,但如果解码执行任何文件IO或其他重要操作,则可能需要以某种方式发送中断信号给php脚本。


我认为你不需要使用sleep(),因为fgets()会阻塞。 - Tom Haigh
这虽然不是很“漂亮”,但是是一个“好”的解决方案 :) - Duncan Roosma

1

我假设 PHP 脚本已经在你的电脑上并返回了有用的数据。我能想到的第一个 -不是很优雅的- 解决方案如下: 确保你的电脑已安装 PHP 命令行,以便能够从命令行运行 PHP 脚本。要从 C# 中执行命令行工具 请参阅此处的代码。现在返回的数据可能需要由你的 C# 程序处理。


谢谢提供链接,它很好地扩展了上面的答案。 - Duncan Roosma

1

我从未尝试过这个方法,也不认识任何人使用过,但我记得曾经听说过这个项目,所以想把它作为你的一个可能选择。

Phalanger 是一个编译器项目,可以将 PHP 代码编译成 IL,因此您可以使用它,然后直接从您的代码中引用管理程序集。


0
如果格式是正则表达式,您可以尝试将其放入应用程序设置文件中(不是资源,这些是与应用程序一起编译的,您无法在不重新编译应用程序的情况下更改它们)。
应用程序设置不能被用户更改,但您可以通过编辑XML来更改它们。
或者,您可以将设置设置为用户模式,然后可以从应用程序代码内部更改格式。

很遗憾,它不是正则表达式,更像是十六进制和位移操作。 - Duncan Roosma

0
为什么不直接从C#启动PHP脚本,将其输出结果写入文件,然后将该文件作为C#程序的输入呢?

0
个人而言,我会建立一个带有适当且稳定API的PHP Web服务,C#项目可以访问该服务,在Web服务中实现制造商提供的PHP类,并将其留下。

那似乎是“最好”的解决方案,但我们(公司)在PHP方面没有太多经验,因此需要花费相当长的时间,而这是昂贵的。 - Duncan Roosma
你考虑过找一位有经验的 PHP 自由职业者吗?这不应该超过半天的时间。 - user32826

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接