Wednesday, December 28, 2011

Calling a perl subroutine from PHP scripts

I spent a good part of my Christmas vacation in figuring out how to call a perl subroutine from a PHP script. There are several reasons why you would like to do that. The first and foremost may be because you don't want to replicate all your perl subroutines to PHP in order to use it. The other issues may be incompatibilities. The one I face is on incompatibility of my PHP version to run oracle queries which can only be solved at the sys admin level.On the other hand the perl/CGI interface for oracle just works fine.

There are 3 levels this task can be achieved:
1. We will see how to pass absolute values to perl subroutines.
2. Pass variables to perl subroutines and
3. Collect return values from the perl subroutine

Following are some points to be remembered:


1. If your perl subroutines are packed into perl packages then they are good to go (e.g; The file should begin with a package "name"; header and the end of the file should have a 1; )
2. Do not use <include "package name"> inside the PHP script.
3. Initialize a string with perl commands e.g; $command='perl -MpackageName -e "packageName::subroutine(arg,arg,arg)"'
4. Call system($command); from the php script. Do not use backticks (`)

Here is an example of passing absolute value to perl subroutine:

##Package Test ###
#!usr/bin/perl -w
package Test;

sub printNames
{
my $name1 = shift;
my $name2 = shift;

print "The names are $name1 and $name2\n";

}

1;

## save it as Test.pm

Level1: Passing an absolute value into the perl subroutine:

# test.php
<?
$command='perl -MTest -e "Test::printNames(Guest1,Guest2)"';
system($command);
?>
#Open browser and run test.php :

The names are Guest1 and Guest2



Level2: Passing a PHP variable into the perl subroutine:

<?


$arg   ="guest1 and guest2";
$arg1 ="guest3 and guest4";

$command = "perl -MTest -e 'Test::printNames("$arg","$arg1")'";
system($command);

?>

# Open browser and run the command:


The names are guest1 and guest2 and guest3 and guest4

Level3: Collecting the return values from perl subroutine as PHP array

Instead of running PHP "system" command, run "exec". Print the outputs from inside the perl subroutine, that can be captured by exec. Now the perl subroutine will undergo slight modification:

##Package Test ###
#!usr/bin/perl -w
package Test;

sub calculateVal
{
my $val1 = shift;
my $val2 = shift;

$val1 *= 20;
$val2 /= 3;

print $val1;
print $val2;

}

1;

---

<?



$arg   =10;
$arg1 =300;

$command = "perl -MTest -e 'Test::printVal($arg,$arg1)'";
$out = array();
$tmp = exec($command,$out);
print_r($out);
?>

# Output

Array 
(
[0] => 200
[1] => 100
)


NOTE: Multidimensional perl arrays can also be passed by printing the value from inside the perl subroutine.

7 comments:

KK said...

how to use the perl module like
use strict;
use Data::Dumper;
use DateTime;
use JSON;
use LWP::Simple;

when calling the perl script from the php?

Please let me know.

ANU said...

Being new to the blogging world I feel like there is still so much to learn. Your tips helped to clarify a few things for me as well as giving..
iOS Training in Chennai
Android Training in Chennai
php Training in Chennai

Sucheta said...

Thank you guys for the comments! I have not been posting regularly due to my work pressure, but will resume shortly.

Priya Kannan said...

Usually I do not read post on blogs, but I would like to say that this write-up very forced me to try and do it! Your writing style has been surprised me. Great work admin.Keep update more blog.
PHP Training in Chennai

Sucheta Tripathy PI @ Computational Genomics Group at IICB, Kolkata said...

Thank you!

john stany said...


I am expecting more interesting topics from you. And this was nice content and definitely it will be useful for many people.

Android App Development Company

Sucheta Tripathy PI @ Computational Genomics Group at IICB, Kolkata said...

Thanks for the comment! I have become little bit irregular, but expecting to get back with more interesting contents.