Skip to content

maaarghk/php-ext-perl

 
 

Repository files navigation

What is php-ext-perl?
=====================

This extension allows embedding of Perl interpreter into PHP 8 to:

  * execute Perl files
  * evaluate Perl code
  * access values of Perl variables
  * call Perl subroutines
  * instantiate and manipulate of Perl objects

It is based on the work of Dmitry Stogov who wrote the PHP 5 extension and was
mostly rewritten for PHP 8.

Requirements
============

PHP 8.0.0 or later
Tested on Perl 5.28 and 5.38
Linux

Compilation
===========

phpize
./configure
make test

Installation
============

sudo make install

Add to php.ini:
extension=perl.so

PHP API
=======

  new Perl()
  ----------
    Creates perl interpreter. It allows

    * reading and modifying of Perl variables
    * calling Perl functions
    * evaluating Perl code
    * loading and executing exteranl Perl files

    Examples:
      $perl = new Perl();
      var_dump($perl->x);        // print scalar Perl variable - $x
      var_dump($perl->array->x); // print array Perl variable - @x
      var_dump($perl->hash->x);  // print hash Perl variable - %x
      $perl->func();             // call Perl function 'func' in void context
      $x = $perl->func();        // call Perl function 'func' in scalar context
      $y = $perl->array->func(); // call Perl function 'func' in array context            
      $y = $perl->hash->func();  // call Perl function 'func' in hash context

      $perl->eval('use Digest::MD5');
      echo $perl->{'Digest::MD5::md5_hex'}('Hello');

  
  Perl->eval($perl_code)
  ----------------------
    Evaluates Perl code and returns result. If Perl code is invalid it will
    throw PHP exception. 

    Exampes:
      $perl = new Perl();
      $perl->eval('require "test.pl";');
      echo $perl->eval($x.'+'.$y.';');
      $perl->eval('$z='.$x.'+'.$y.';');

    By default Perl code is evaluated in scalar context, but it can be 
    evaluated in array or hash context too.

    Exampes:
      $perl = new Perl();
      $perl->eval('("a","b","c")');                  // eval in void context
      var_dump($perl->eval('("a","b","c")'));        // eval in scalar context
      var_dump($perl->array->eval('("a","b","c")')); // eval in array context
      var_dump($perl->hash->eval('("a","b","c")'));  // eval in hash context


  Perl->require($perl_file_name)
  ------------------------------
    Loads and executes Perl file. It doesn't return any value. If required Perl
    file doesn't exist or invalid it will throw PHP exception.

    Examples:
      $perl = new Perl();
      $perl->require('test.pl');

  new Perl($perl_class_name[, $constructor = "new"[, ...]])
  -----------------------------------------------------
    Creates an instance of Perl class through calling specified constructor
    or "new" if constructor is not specified. Additional parameters passed
    to Perl's constructor. The created object allows:

    * reading and modifying of object properties
    * calling methods
    * cloning

    Examples:
      $x = new Perl("Test");
      $y = new Perl("Test","copy",$x);
      $z = clone $y;
      echo $z->property;
      echo $z->method(1,2,3);

    Methods can be called in array or hash context in the same way as Perl
    functions, but all properties are acessable directly (without array or
    hash modifiers).

    Examples:
      $x = new Perl("Test");
      $x->f();                  // call method "f" in void context
      var_dump($x->f());        // call method "f" in scalar context
      var_dump($x->array->f()); // call method "f" in array context
      var_dump($x->hash->f());  // call method "f" in hash context

Known limitation - proxy objects
================================

Perl objects are passed between Perl and PHP by reference. All other data types
(including arrays and hashes) are passed by value. So modification of Perl's
arrays and hashes in PHP will not have effect in Perl.

    $perl->eval("@x = (1,2,3)");
    $perl->eval('print @x'); // prints 123
    $x = $perl->array->x;
    $x[1] = 9; // $x = [1,9,3];
    $perl->eval('print @x'); // prints 123
     
Previously, the following could be done:

    $perl->eval("@x = (1,2,3)");
    $perl->eval('print @x'); // prints 123
    $x = &$perl->array->x; // we return a proxy object because of the &
    $x[1] = 9;
    $perl->eval('print @x'); // prints 193

However, PHP 8.0 deprecated line 4 of the above example. It can be reimplemented
as it has been in php_ffi by a special property called "data" or something, but
I personally don't require that feature so I haven't implemented it yet.

Known limitation - calling internal Perl functions
==================================================

You can't call internal perl functions (print, die, etc) using the
$perl->function() syntax.

TODO
====

* Some tests don't pass because perl hashes are returned in random order. I have
  mitigated this in some places but the remaining ones would no longer be a good
  test if changed. Maybe something clever could be done with EXPECTREGEX or a
  patch could be made upstream or maybe output buffer could be checked by the
  test itself.

* Re-implement proxy scalar object writing

Support
=======

I need to maintain this for production anyway, so bug reports and PRs are
welcome. Ideally, make a PR with a phpt file which fails.

This version of the extension has not been tested on Windows, or with Perl
versions other than 5.28 and 5.32.

About

This php extension embeds Perl Interpreter into PHP.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C 51.7%
  • PHP 46.9%
  • Other 1.4%