Lately I've been experimenting with using PHP and perl together, and I've started using PHP::Interpreter. It is a very cool module that allows both embedding perl code in PHP and vica verca. It has an interesting history being sponsored by Portugal Telecom (kudos to them).

I initially found the module difficult to install (and others with me, e.g. here, and here). PHP::Interpreter obviously depends on having both PHP and the PHP sources installed, and some of the difficulty lays in how to locate the local PHP binaries (if at all present).

PHP is renowned for its' low barrier of entry, so I figured a PHP interface to perl should install as easily as possible. This motivates the attempt of making PHP::Interpreter easier to install.

The current Makefile.PL has a number of unfortunate properties:

The module PHP uses another approach to determine the underlying PHP install: It's Makefile.PL calls `php-config` and simply dies if it's not in path. I like this die hard approach, since it makes it very clear what is missing as soon as a (possible) problem is detected.

Please comment the below attempt to improve on Makefile.PL. I'll probably contact the maintainer later on.

use strict; use warnings; use ExtUtils::MakeMaker; use Config; use File::Spec::Functions qw(catdir); # Check if File::Find is present eval { use File::Find; }; my $filefind = (!$@) ? 1 : 0; # These header files must be present for PHP::Interpreter to compile my %headers = (); $headers{$_}++ for qw ( php_config.h php.h php_ini.h php_main.h zend.h zend_API.h zend_compile.h zend_ini.h SAPI.h TSRM.h ); # Return true if files in headers hash are found, otherwise die sub check_headers { my $inc = shift; die "Need an argument" if !$inc; print "Checking header files...\n"; # Replace -I at beginning of string and chop of newline character my @incdirs = map { s/^-I//g; chomp; $_ } split(/ /, $inc); for (@incdirs) { die "No such directory: '$_'" if (!-d); print "using incdir '$_'\n"; } # Make sure header files are present my $finder = sub { return if (!-f $_ or !exists($headers{$_})); print "Found $File::Find::name\n"; delete $headers{$_}; }; # Try to find all files in headers - delete hash entries when found. # Any remaining hash key indicates a necessary file is missing. find(\&$finder, @incdirs); die "Missing header files: " . join(q{, }, keys %headers) if (keys % +headers); return 1; } # Execute 'php-config' for each variable. Dies if executable is not # in path. my %conf = map { my $a = `php-config --$_`; die "Error: php-config --$_ failed\n" unless $a; chomp $a; $_ => $a; } qw(includes prefix version ldflags); # Get php version print "using php version $conf{version}\n"; $conf{version} =~ s/^(\d+).*/$1/; # Need major version only die "Unsupported PHP version" if ($conf{version} != 5); # Get prefix. Use script argument as prefix, otherwise use value from # 'php-config' my $prefix = shift @ARGV || ($conf{prefix}); die "Failed to find php root" if (!defined($prefix) or !-d $prefix); print "using prefix $prefix\n"; # Get include directories my $includes = "-I" . catdir($prefix, 'include') . " " . $conf{include +s}; print "using includes $includes\n"; # Get libraries my @lddlflags = ($Config{lddlflags}, $conf{ldflags}); push @lddlflags, "-L" . catdir $prefix, "lib"; my $php_embedlib_path = "-L" . catdir $prefix, "lib"; push @lddlflags, $php_embedlib_path; print "using lddlflags " . join(q{ }, @lddlflags) . "\n"; # Libs = lddlflags + php-version my @libs = ("$php_embedlib_path"); push @libs, "-lphp$conf{version}"; print "using libs " . join(q{ }, @libs) . "\n"; my @ofiles = ('PHP.o', 'phpinterp.o', 'phpfuncs.o'); # Check that header files are present if File::Find is installed ($filefind) ? check_headers($includes) : print "Module File::Find not installed. Header files check skipped +.\n"; WriteMakefile( CCFLAGS => '-g', OBJECT => join(' ', @ofiles), NAME => 'PHP::Interpreter', LIBS => join(' ', @libs), LDDLFLAGS => join(' ', @lddlflags), INC => $includes, VERSION_FROM => 'lib/PHP/Interpreter.pm', PREREQ_PM => { # Just required for testing. 'Test::More' => 0, 'IO::File' => 0 }, ); __END__ =pod =head1 NAME Makefile.PL - Makefile for PHP::Interpreter =head1 SYNOPSIS perl Makefile.PL [prefix] =head1 OPTIONS prefix - directory root for PHP install, e.g. /usr/local or C:\\Program Files\\PHP =head1 DESCRIPTION This creates a makefile for PHP::Interpreter. PHP::Interpreter depends on having both PHP and PHP sources installed. This script uses the executable I<php-config> to determine how PHP is configured. This script will die unless I<php-config> is installed. PHP::Interpreter works with PHP5 only. This script will perform header files check if module I<File::Find> is installed =head1 SEE ALSO php php-config =cut
Fri Nov 7 10:11:48 CET 2008: Committed changes to the PHP::Sandwich repository.

Tue Nov 11 21:51:28 CET 2008: See also Re: use PHP::Interpreter throws undefined symbol: zend_ce_traversable for PHP installation notes.

--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]

In reply to Making PHP::Interpreter easier to install by andreas1234567

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.