Skip to content

php-java/php-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

169 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PHPJava - JVM Emulator by PHP

contributions welcome Compatibility Build Status Total Downloads License: MIT

What is the PHPJava?

The PHPJava is experimental library which emulate JVM (a.k.a. Java Virtual Machine) by PHP 🐘 The PHPJava proceed to read binary from pre-compiled Java file(s) β˜• This project reference to Java Virtual Machine Specification documentation when We makes.

We welcoming to contributions this project πŸ’ͺ

Requirements

  • PHP >= 7.2
  • Composer
  • ext-zip

Not currently supported

Sorry, I do not have enough time (T_T)

  • Implements
  • Event
  • double/float calculation.
  • Many built-in libraries (ex. java.lang.xxx, java.io.xxx and so on)
  • etc...

Quick start

    1. Install the PHPJava into your project.
$ composer require memory-agape/php-java
    1. Write Java
class HelloWorld 
{
    public static void main(String[] args)
    {
        System.out.println(args[0] + " " + args[1]);
    }
}
    1. Compile Java
$ javac -UTF8 /path/to/HelloWorld.java
    1. Call to main method as following.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

(new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class')))
    ->getInvoker()
    ->getStatic()
    ->getMethods()
    ->call(
        'main',
        ["Hello", 'World']
    );
    1. Get a result
$ php /path/to/HelloWorld.php
Hello World

Java Archive (Execute to *.jar file)

    1. Build your java files to class. Building example is below.
$ javac -encoding UTF8 -d build src/*
$ cd build && jar -cvfe ../Test.jar Test *
    1. execute jar on PHPJava with enrtypoint or your targeted method.
<?php
use PHPJava\Core\JavaArchive;

(new JavaArchive('Test.jar'))->execute();

// or
(new JavaArchive('Test.jar'))
    ->getClassByName('Test')
    ->getInvoker()
    ->getStatic()
    ->getMethods()
    ->call(
        'main',
        []
    );

Get/Set a static fields

  • ex) Set or Get a static fields as follows.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

$staticFieldAccessor = (new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class')))
    ->getInvoker()
    ->getStatic()
    ->getFields();

// Set
$staticFieldAccessor->set('fieldName', 'value');

// Get
echo $staticFieldAccessor->get('fieldName');

Call to a static method

  • ex) Call to static method as follows.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

(new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class')))
    ->getInvoker()
    ->getStatic()
    ->getMethods()
    ->call(
        'methodName',
        $firstArgument,
        $secondArgument,
        $thirdArgument,
        ...
    );

// Or if called method have return value then you can store to variable.
$result = (new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class')))
   ->getInvoker()
   ->getStatic()
   ->getMethods()
   ->call(
       'methodWithSomethingReturn',
       $firstArgument,
       $secondArgument,
       $thirdArgument,
       ...
   );

// The $result you want is output.
echo $result;

Get/Set a dynamic fields

If you want to get/set dynamic fields, you need call to construct method on Java by PHPJava.

  • ex) Call dynamic field as following.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

$javaClass = new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class'));

$javaClass->getInvoker()->construct();

$dynamicFieldAccessor = $javaClass
    ->getInvoker()
    ->getDynamic()
    ->getFields();

// Set
$dynamicFieldAccessor->set('fieldName', 'value');

// Get
echo $dynamicFieldAccessor->get('fieldName');

Call to a dynamic method

If you want to get/set dynamic method (same as field), you need call to construct method on Java by PHPJava.

  • ex) Call dynamic method as following.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

$dynamicMethodAccessor = (new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class')))
     ->getInvoker()
     ->construct()
     ->getDynamic()
     ->getMethods(); 

$dynamicMethodAccessor
    ->call(
        'methodName',
        $firstArgument,
        $secondArgument,
        $thirdArgument,
        ...
    );

// Or if called method have return value then you can store to variable.
$dynamicMethodAccessor
   ->call(
       'methodWithSomethingReturn',
       $firstArgument,
       $secondArgument,
       $thirdArgument,
       ...
   );

// The $result you want is output.
echo $result;

Output PHPJava operations

  • Output debug trace as following if you want to show operated log.
<?php
use PHPJava\Core\JavaClass;
use PHPJava\Core\JavaClassFileReader;

$javaClass = new JavaClass(new JavaClassFileReader('/path/to/HelloWorld.class'));

$javaClass
    ->getInvoker()
    ->getStatic()
    ->getMethods()
    ->call(
        'main',
        ["Hello", 'World']
    );

// Show debug traces.
$javaClass->debug();
  • Outputted debug trace is below.
[method]
public static void main(java.lang.String[])

[code]
<0xb2> <0x00> <0x02> <0x2a> <0x03> <0x32> <0xb6> <0x00> <0x03> <0xb2> <0x00> <0x02> <0x2a> <0x04> <0x32> <0xb6> <0x00> <0x03> <0xb2> <0x00>
<0x02> <0x2a> <0x05> <0x32> <0xb6> <0x00> <0x03> <0xb1>

[executed]
      PC | OPCODE | MNEMONIC             | OPERANDS   | LOCAL STORAGE  
---------+--------+----------------------+------------+-----------------
       0 | 0xB2   | getstatic            | 0          | 1              
       3 | 0x2A   | aload_0              | 1          | 1              
       4 | 0x03   | iconst_0             | 2          | 1              
       5 | 0x32   | aaload               | 3          | 1              
       6 | 0xB6   | invokevirtual        | 2          | 1              
       9 | 0xB2   | getstatic            | 0          | 1              
      12 | 0x2A   | aload_0              | 1          | 1              
      13 | 0x04   | iconst_1             | 2          | 1              
      14 | 0x32   | aaload               | 3          | 1              
      15 | 0xB6   | invokevirtual        | 2          | 1              
      18 | 0xB2   | getstatic            | 0          | 1              
      21 | 0x2A   | aload_0              | 1          | 1              
      22 | 0x05   | iconst_2             | 2          | 1              
      23 | 0x32   | aaload               | 3          | 1              
      24 | 0xB6   | invokevirtual        | 2          | 1              
      27 | 0xB1   | return               | 0          | 1              
---------+--------+----------------------+------------+-----------------
  • [method] is showing called method.
  • [code] is showing JVM's real programs.
  • [executed] is showing executed programs.
    • PC is showing Program Counter.
    • OPCODE is showing Operation Codes.
    • MNEMONIC is naming Operation Codes.
    • OPERANDS is showing stacked items on memory.
    • LOCAL STORAGE is showing stacked items on a method.

PHP problems

  • The PHP is cannot calculating big numbers because of PHP is different to the Java. But the PHPJava use bcmath functions and gmp functions to a certain extent to cover to calculate. The PHPJava return valued is mixed why therefore We recommend to cast to string on the PHPJava.

  • The PHPJava cannot cover to Java's types completely because of PHP is different to the Java. The Java and the PHPJava comparison table is below.

Java PHPJava
null null
boolean \PHPJava\Kernel\Types\_Boolean (including __toString)
char \PHPJava\Kernel\Types\_Char (including __toString), string
byte \PHPJava\Kernel\Types\_Byte (including __toString), string
short \PHPJava\Kernel\Types\_Short (including __toString), string, int
int \PHPJava\Kernel\Types\_Int (including __toString), string, int
long \PHPJava\Kernel\Types\_Long (including __toString), string, int
float \PHPJava\Kernel\Types\_Float (including __toString), string, float
double \PHPJava\Kernel\Types\_Char (including __toString), string, float

Run unit tests

  • PHPUnit test is below.
$ ./vendor/bin/phpunit tests
  • PHP Coding standards testing is below.
$ ./vendor/bin/phpcs --standard=phpcs.xml src
  • All testing is below.
$ composer run tests

Reference

License

MIT

About

β˜•πŸ˜ Implement JVM by PHP

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors