PHP <-> Perl Bridge using cURL

Using cURL to submit requests from PHP into Perl allows graceful reuse of code with a system with a robust core of Perl code and a PHP web interface.

The Perl code accepts a module name, sub/function name, and a set of parameters.

It includes the module, then tests for the sub. Then assembles the parameters into a request and calls the Perl code. The code returned may be name value pairs, or PHP, for more complex responses.

This code has been edited for brevity, it is an example, not a ready to use solution.

#!/usr/bin/perl

use strict;
use CGI qw(-compile :cgi);

my $q=CGI->new;

print $q->header('text/plain');

my $m=$q->param('module');
my $s=$q->param('sub');
$m=~s/\W//g;

my $path="$ENV{'APPHOME'}/bin/".$m.".pm";

require $path;

my $ms=$m.'::'.$s;

if (Test($ms))
{
        my $x='bridge_'.$m.'("'.$s.'",\%{$q->Vars})';
        eval $x;
        exit 0;
}
else
{
        exit 101;
}
sub Test
{
        my $sub_name=$_[0];
        return ( defined &{ $sub_name } );
}

sub bridge_PERL_CODE
{
        my $r=0;
        my $sub=$_[0];
        my (%parms)=%{$_[1]};

        delete $parms{'module'};
        delete $parms{'sub'};

        SWITCH: for ($sub)
        {
                /^getSystemServices$/ && do
                {
                        my %services;

                        my $status=PERL_CODE::getSystemServices(\%services);

                        # Sample code to generate PHP
                        my ($id,$k,$kk,$s,$t);
                        print '<?php',"\n";
                        $s='$services=array('."\n";
                        for my $k ( keys %services ) 
                        {
                                $id=$services{$k}{'id'};
                                delete $services{$k}{'id'};
                                $s.='\''.$id.'\'=>array('."\n";
                                for $kk ( keys %{$services{$k}} )
                                {
                                        $t=$services{$k}{$kk};
                                        $t =~ s/(['"])/\\$1/g;
                                        $s.="\t".'\''.$kk.'\'=>\''.$t.'\',';
                                }
                                $s=substr $s,0,-1;
                                $s.='),'."\n";
                        }
                        $s=substr $s,0,-2;
                        $s.=');';

                        print $s,"\n";

                        print '?>';

                        $r=$status;

                        last SWITCH;
                };
                /^getServiceParms$/ && do
                {
                        my $serviceId=$parms{'serviceId'};
                        my %parmValues;

                        my ($status,$msg)=PERL_CODE::getServiceParms($serviceId, \%paramValues);

                        # Sample code to generate name/value pairs
                        my ($k,$v);
                        while (($k, $v) = each(%parmValues))
                        {
                             print $k.'='.$v,"\n";
                        }
                        print 'status='.$status,"\n";
                        print 'msg='.$msg,"\n";

                        $r=$status;

                        last SWITCH;
                };
                #DEFAULT
                {
                        # Error - Should never get here
                        $r=-1;
                        last SWITCH;
                };
        }
        return $r;
}

<?php
function curl_request($sPost=null,$bHandleAsPHP=false)
{
        $cURL=curl_init();
        curl_setopt($cURL,CURLOPT_URL,"http://localhost/cgi-bin/bridge.pl");
        curl_setopt($cURL,CURLOPT_POST, TRUE);
        curl_setopt($cURL,CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($cURL,CURLOPT_POSTFIELDS,$sPost);
        $cResponse=trim(curl_exec($cURL));
        curl_close($cURL);
        return handle_response($cResponse,$bHandleAsPHP);
}

function handle_response($sResponse=null,$bHandleAsPHP=false)
{
        if (!$bHandleAsPHP)
        {
                $aResponseLines=$aResult=array();
                $aResponseLines=explode("\n",$sResponse);
                if (count($aResponseLines)>0)
                        foreach ($aResponseLines as $k => $v)
                        {
                                $e=strpos($v,'=');
                                if ($e!==false)
                                        $aResult[substr($v,0,$e)]=substr($v,$e+1);
                        }
        }
        else
        {
                $sResponse=str_replace(array('<?php','?>'),'',$sResponse);
                $sResponse.="\n".'$vars=get_defined_vars();';
                eval($sResponse);
                unset($vars['sResponse'],$vars['bHandleAsPHP']);
                $aResult=$vars;
        }
        return $aResult;
}

/* Call across the bridge, expecting PHP in response */
function getSystemServices()
{
        return curl_request('module=PERL_CODE&sub=getSystemServices',true);
}