<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mm &#187; PHP</title>
	<atom:link href="http://markmaunder.com/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://markmaunder.com</link>
	<description></description>
	<lastBuildDate>Fri, 30 Jul 2010 05:56:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to integrate PHP, Perl and other languages on Apache</title>
		<link>http://markmaunder.com/2009/how-to-integrate-php-and-perl-or-any-other-languages-on-apache/</link>
		<comments>http://markmaunder.com/2009/how-to-integrate-php-and-perl-or-any-other-languages-on-apache/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 17:55:21 +0000</pubDate>
		<dc:creator>mark</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://markmaunder.com/?p=324</guid>
		<description><![CDATA[I have this module that a great group of guys in Malaysia have put together. But their language of choice is PHP and mine is Perl. I need to modify it slightly to integrate it. For example, I need to add my own session code so that their code knows if my user is logged in or not and who they are.
I started writing PHP but quickly started duplicating code I&#8217;d already written in Perl. Fetch the session from the ...]]></description>
			<content:encoded><![CDATA[<p>I have this module that a great group of guys in Malaysia have put together. But their language of choice is PHP and mine is Perl. I need to modify it slightly to integrate it. For example, I need to add my own session code so that their code knows if my user is logged in or not and who they are.</p>
<p>I started writing PHP but quickly started duplicating code I&#8217;d already written in Perl. Fetch the session from the database, de-serialize the session data, that sort of thing. I also ran into issues trying to recreate my Perl decryption routines in PHP. [I use non-mainstream ciphers]</p>
<p>Then I <a href="http://devzone.zend.com/article/1712">found ways to run Perl inside PHP and vice-versa</a>. But I quickly realized that&#8217;s a very bad idea. Not only are you creating a new Perl or PHP interpreter for every request, but you&#8217;re still duplicating code, and you&#8217;re using a lot more memory to run interpreters in addition to what mod_php and mod_perl already run.</p>
<p>Eventually I settled on creating a very lightweight wrapper function in PHP called doPerl. It looks like this:</p>
<p>$associativeArrayResult = doPerl(functionName, associativeArrayWithParameters);</p>
<pre>function doPerl($func, $arrayData){
 $ch = curl_init();
 $ip = '127.0.0.1';
 $postData = array(
 json =&gt; json_encode($arrayData),
 auth =&gt; 'myPassword',
 );
 curl_setopt($ch,CURLOPT_POST, TRUE);
 curl_setopt($ch,CURLOPT_POSTFIELDS, $postData);
 curl_setopt($ch, CURLOPT_URL, "http://" . $ip . "/webService/" . $func . "/");
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $output = curl_exec($ch);
 curl_close($ch);
 $data = json_decode($output, TRUE);
 return $data;
}</pre>
<p><code> </code></p>
<p>On the other side I have a very fast mod_perl handler that only allows connections from 127.0.0.1 (the local machine). I deserialise the incoming JSON data using Perl&#8217;s JSON::from_json(). I use eval() to execute the function name that is, as you can see above, part of the URL. I reserialize the result using Perl&#8217;s JSON::to_json($result) and send it back to the PHP app as the HTML body.</p>
<p>This is very very fast because all PHP and Perl code that executes is already in memory under mod_perl or mod_php. The only overhead is the connection creation, sending of packet data across the network connection and connection breakdown. Some of this is handled by your server&#8217;s hardware. [And of course the serialization/deserialization of the JSON data on both ends.]</p>
<p>The connection creation is a three way handshake, but because there&#8217;s no latency on the link it&#8217;s almost instantaneous. The transferring of data is faster than a network because the MTU on your lo interface (the 127.0.0.1 interface) is 16436 bytes instead of the normal 1500 bytes. That means the entire request or response fits inside a single packet. And connection termination is again just two packets from each side and because of the zero latency it&#8217;s super fast.</p>
<p>I use JSON because it&#8217;s less bulky than XML and on average it&#8217;s faster to parse across all languages. Both PHP and Perl&#8217;s JSON routines are ridiculously fast.</p>
<p>My final implementation on the PHP side is a set of wrapper classes that use the doPerl() function to do their work. Inside the classes I use caching liberally, either in instance variables, or if the data needs to persist across requests I use <a href="http://php.net/manual/en/book.apc.php" target="_blank">PHP&#8217;s excellent APC cache</a> to store the data in shared memory.</p>
<p><strong>Update: </strong>On request I&#8217;ve posted the<a href="/webServices.zip"> perl web service handler for this here</a>. The Perl code allows you to send parameters via POST using either a query parameter called &#8216;json&#8217; and including escaped JSON that will get deserialized and passed to your function, or you can just use regular post style name value pairs that will be sent as a hashref to your function. I&#8217;ve included one test function called hello() in the code. Please note this web service module lets you execute arbitrary perl code in the web service module&#8217;s namespace and doesn&#8217;t filter out double colon&#8217;s, so really you can just do whatever the hell you want. So I&#8217;ve included two very simple security mechanisms that I strongly recommend you don&#8217;t remove. It only allows requests from localhost, and you must include an &#8216;auth&#8217; post parameter containing a password (currently set to &#8216;password&#8217;). You&#8217;re going to have to implement the MM::Util::getIP() routine to make this work and it&#8217;s really just a one liner:</p>
<pre>sub getIP {
 my $r = shift @_;
 return $r-&gt;headers_in-&gt;{'X-Forwarded-For'} ?
    $r-&gt;headers_in-&gt;{'X-Forwarded-For'} :
    $r-&gt;connection-&gt;get_remote_host();
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://markmaunder.com/2009/how-to-integrate-php-and-perl-or-any-other-languages-on-apache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
