{"id":24017438,"url":"https://github.com/php-java/php-java","last_synced_at":"2025-05-16T17:04:54.548Z","repository":{"id":26617547,"uuid":"30072897","full_name":"php-java/php-java","owner":"php-java","description":"☕🐘 Implement JVM by PHP ","archived":false,"fork":false,"pushed_at":"2024-04-30T02:15:32.000Z","size":59447,"stargazers_count":444,"open_issues_count":1,"forks_count":35,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-16T17:04:20.238Z","etag":null,"topics":["java","jvm","php"],"latest_commit_sha":null,"homepage":"https://i.mem.ooo/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/php-java.png","metadata":{"files":{"readme":"README-ja.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-30T13:23:35.000Z","updated_at":"2025-05-09T08:29:23.000Z","dependencies_parsed_at":"2023-12-25T02:46:04.659Z","dependency_job_id":null,"html_url":"https://github.com/php-java/php-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-java%2Fphp-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-java%2Fphp-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-java%2Fphp-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-java%2Fphp-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/php-java","download_url":"https://codeload.github.com/php-java/php-java/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254573588,"owners_count":22093731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jvm","php"],"created_at":"2025-01-08T09:18:00.549Z","updated_at":"2025-05-16T17:04:54.528Z","avatar_url":"https://github.com/php-java.png","language":"PHP","readme":"# PHPJava - JVM Emulator by PHP\n[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/dwyl/esta/issues)\n![Compatibility](https://img.shields.io/badge/Compatibility-7.2%20and%20greater-green.svg) \n[![Build Status](https://travis-ci.org/php-java/php-java.svg?branch=master)](https://travis-ci.org/php-java/php-java)\n[![Total Downloads](https://poser.pugx.org/php-java/php-java/downloads)](https://packagist.org/packages/php-java/php-java)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n\u003cp align=\"center\"\u003e\u003cimg src=\"./docs/img/logo.png\" height=\"300\"\u003e\u003c/p\u003e\n\n# What is PHPJava?\nPHPJava は PHP で JVM (Java Virtual Machine) をエミュレーションさせたり、JVM 上で実行できる中間コードのコンパイラを提供している実験的なライブラリです 🐘\nPHPJava は予めコンパイルされた Java ファイル(一般的には class ファイル)を読み込み逐次処理をしていきます ☕ \nそして、 PHPJava は Java を **ブリッジや通信をするためのライブラリではありません**。\nPHPJava は **100% PHP のみ** で動きます\nこのプロジェクトは [Java Virtual Machine Specification](https://docs.oracle.com/javase/specs/jvms/se11/html/index.html) を参考に創られています。\n\n私達は心よりあなたのコントリビューションをお待ちしています 💪\n\nコントリビューションガイド:\n- [コントリビューションガイド](https://github.com/php-java/php-java/wiki/The-Contribution-Guide) \n\n## ドキュメント\n\n## Java Virtual Machine\n- [English](./README.md)\n- [日本語](./README-ja.md)\n\n## 中間コードコンパイラ\n- [English](./docs/compiler/README.md)\n- [日本語](./docs/compiler/README-ja.md)\n\n## PHP のシンタックスによる JVM 言語\n- [English](./docs/jvm-lang/README.md)\n- [日本語](./docs/jvm-lang/README-ja.md)\n\n## デモ\n![DEMO](https://user-images.githubusercontent.com/1282995/58679222-87070880-839d-11e9-8c98-978fdd0bb015.gif)\n\n## 必須環境\n- PHP \u003e= 7.2\n- Composer\n- ext-zip\n\n## PHPJava を実行ファイルとして実行する \nPHPJava は実行ファイルとして処理させることが可能です。\n\n### クラスファイルを動かす場合\n```shell\n./vendor/bin/PHPJava HelloWorld\n```\n\nまたは、\n\n```shell\n./vendor/bin/PHPJava HelloWorld.class\n```\n\n### Jar ファイルを動かす場合\n```shell\n./vendor/bin/PHPJava -m jar HelloWorld.jar\n```\n\n### ヘルプを表示したい場合\n\n```shell\n./vendor/bin/PHPJava -h\n```\n\n## クイックスタート\n1) PHPJava をインストールします。\n```\n$ composer require php-java/php-java:dev-master\n```\n\n2) Java を書きます。\n```java\nclass HelloWorld \n{\n    public static void main(String[] args)\n    {\n        System.out.println(args[0]);\n    }\n}\n```\n\n3) Java をコンパイルします。\n```\n$ javac -encoding UTF8 /path/to/HelloWorld.java\n```\n\n4) main メソッドを呼びます。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\nJavaClass::load('HelloWorld')\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetMethods()\n    -\u003ecall(\n        'main',\n        [\"Hello World!\"]\n    );\n\n// または、以下のようにファイルパスを指定することも可能です。 \n(new JavaClass(new JavaCompiledClass(new FileReader('/path/to/HelloWorld.class'))))\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetMethods()\n    -\u003ecall(\n        'main',\n        [\"Hello World!\"]\n    );\n```\n\n5) 結果を取得します。\n```\n$ php /path/to/HelloWorld.php\nHello World!\n```\n\n## Java Archive (*.jar ファイルの実行)\n\n1) Jar ファイルを作成します。\n```\n$ javac -encoding UTF8 -d build src/*\n$ cd build \u0026\u0026 jar -cvfe ../Test.jar Test *\n```\n\n2) エントリーポイントを指定するか、またはすでに指定されたエントリーポイントをもとに Jar ファイルを動かします.\n2) Execute the jar on PHPJava with either an enrtypoint or your target method.\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaArchive;\n\n// execute メソッドは初期パラメータを定義していないため、\n// エントリーポイントを呼び出すための execute メソッドは必ず、 パラメータを指定する必要があります。\n(new JavaArchive('Test.jar'))-\u003eexecute([]);\n\n// または、\n(new JavaArchive('Test.jar'))\n    -\u003egetClassByName('Test')\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetMethods()\n    -\u003ecall(\n        'main',\n        []\n    );\n```\n\n### 静的フィールドの取得または代入\n\n- 下記のように取得または代入を行うことが可能です\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$staticFieldAccessor = JavaClass::load('HelloWorld')\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetFields();\n\n// 代入\n$staticFieldAccessor-\u003eset('fieldName', 'value');\n\n// 取得\necho $staticFieldAccessor-\u003eget('fieldName');\n```\n\n### 静的メソッドの呼び出し\n\n- 下記のように静的メソッドを呼び出します。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\nJavaClass::load('HelloWorld')\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetMethods()\n    -\u003ecall(\n        'methodName',\n        $firstArgument,\n        $secondArgument,\n        $thirdArgument,\n        ...\n    );\n\n// または、メソッドが返り値をもつ場合は、下記のようにして、返り値を変数に代入することが可能です。\n$result = JavaClass::load('HelloWorld')\n   -\u003egetInvoker()\n   -\u003egetStatic()\n   -\u003egetMethods()\n   -\u003ecall(\n       'methodWithSomethingReturn',\n       $firstArgument,\n       $secondArgument,\n       $thirdArgument,\n       ...\n   );\n\n// 返り値を出力します。\necho $result;\n```\n\n\n### 動的フィールドの取得または代入\n- 動的フィールドを取得または代入したい場合は、`construct` メソッド呼ぶ必要があります。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$javaClass = JavaClass::load('HelloWorld');\n\n$javaClass-\u003egetInvoker()-\u003econstruct();\n\n$dynamicFieldAccessor = $javaClass\n    -\u003egetInvoker()\n    -\u003egetDynamic()\n    -\u003egetFields();\n\n// 代入\n$dynamicFieldAccessor-\u003eset('fieldName', 'value');\n\n// 取得\necho $dynamicFieldAccessor-\u003eget('fieldName');\n```\n\n### 動的メソッドの呼び出し\n\n- 動的メソッドを呼びたい場合動的フィールドのように、`construct` メソッド呼ぶ必要があります。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$dynamicMethodAccessor = JavaClass::load('HelloWorld')\n     -\u003egetInvoker()\n     -\u003econstruct()\n     -\u003egetDynamic()\n     -\u003egetMethods(); \n\n$dynamicMethodAccessor\n    -\u003ecall(\n        'methodName',\n        $firstArgument,\n        $secondArgument,\n        $thirdArgument,\n        ...\n    );\n\n// または、メソッドが返り値をもつ場合は、下記のようにして、返り値を変数に代入することが可能です。\n$dynamicMethodAccessor\n   -\u003ecall(\n       'methodWithSomethingReturn',\n       $firstArgument,\n       $secondArgument,\n       $thirdArgument,\n       ...\n   );\n\n// 返り値を出力します。\necho $result;\n```\n\n### Java のビルトインパッケージ内のメソッドの呼び出し\nVer. 0.0.8.5 より通常の `JavaClass::load` と同様の呼び出し方法でビルトインパッケージの呼び出しが可能になりました。\nなお、これは `PHP` の `ReflectionClass` を用いてエミュレートされており、静的なメソッドやフィールドも実際には動的に生成されます。\n\n下記は `java.lang.Math` の呼び出し例です。\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\necho JavaClass::load('java.lang.Math')\n     -\u003egetInvoker()\n     -\u003egetStatic()\n     -\u003egetMethods()\n     -\u003ecall(\n         'pow',\n         2,\n         4\n     ); \n````\n\n上記の結果は `16` となります。\n\n\n### あいまいなメソッドを PHPJava から呼び出す場合\n- PHP は Java と比べると型がだいぶ曖昧です。そのため、 PHPJava では正確にメソッドを呼び出すための手段をいくつか用意しています。\n- 以下は、 `long` パラメータを受け取るメソッドを呼び出す場合の例です。\n\n#### [推奨] パラメータを `\\PHPJava\\Kernel\\Types\\Long_ ` にする。\n##### Java\n```java\nclass Test\n{\n    public static void includingLongTypeParameter(long n)\n    {\n        System.out.println(n);\n    }\n}\n```\n\n##### PHP\n```php\n\u003c?php\n$javaClass-\u003egetInvoker()-\u003egetStatic()-\u003egetMethods()-\u003ecall(\n    'includingLongTypeParameter',\n    new \\PHPJava\\Kernel\\Types\\Long_ (1234)\n);\n```\n\nこの例は `1234` を返却します。\n\n#### strict オプションを `無効` にする\n##### PHP\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$javaClass = JavaClass::load(\n    'HelloWorld',\n    [\n        'strict' =\u003e false,\n    ]\n);\n```\n\n### ラインタイムオプション\n- `JavaClass` または、 `JavaArchive` で使用可能なランタイムオプションは下記のとおりです。\n\n| オプション名 | 型 | デフォルト値 | 概要 | 対象 |\n|:--------|:------|:--------|:------------|:---------|\n| entrypoint | string または、 null | null | Jar のエントリーポイントを指定します | JavaArchive |\n| max_stack_exceeded | integer | 9999 | オペレーションを最大何回実行できるかを指定します。 | JavaClass |\n| max_execution_time | integer | 30 | 最大実行時間を指定します。 | JavaClass |\n| strict | boolean | true | このオプションが `true` の場合、 PHPJava はメソッド、変数などを厳格に評価し実行します。 `false` の場合は、曖昧に評価して実行します。. | Both |\n| validation.method.arguments_count_only | boolean | false | このオプションが `true` の場合、 クラス解決をして、メソッドを呼び出す際に、引数の数のみを比較します。 | JavaClass |\n| operations.enable_trace | boolean | false | このオプションが `true` の場合、 PHPJava はオペレーションの実行ログを記録します。 | JavaClass |\n| operations.temporary_code_stream | string | php://memory | 実行用のバイトコードの一時保存先を指定します。 | JavaClass |\n| operations.injector.before | callable | null | オペレーション実行前に処理をするトリガーを設定します。 | JavaClass |\n| operations.injector.after | callable | null | オペレーション実行後に処理をするトリガーを設定します。 | JavaClass |\n| log.level | int | Logger::EMERGENCY | `Monolog` によるログの出力レベルを設定します | Both |\n| log.path | string または resource | php://stdout | `Monolog` の出力先を指定します。. | Both |\n| dry_run (未実装) | boolean | false | このオプションが `true` の場合、 JavaClass または JavaArchive の構造のチェックのみを行います。 | Both |\n| env (未実装) | enum | Environment::EXPERIMENTAL | あなたの実行時環境を設定します。 | Both |\n\n- JavaClass でオプションを指定する場合は下記のとおりです。\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$javaClass = JavaClass::load(\n    'HelloWorld',\n    [\n        'max_stack_exceeded' =\u003e 12345,\n        'validation' =\u003e [\n            'method' =\u003e [\n                'arguments_count_only' =\u003e true,\n            ],\n        ],\n    ]\n);\n```\n\n- `GlobalOptions` を使用して設定する場合は下記のとおりです。\n```php\n\u003c?php\nuse PHPJava\\Core\\JVM\\Parameters\\GlobalOptions;\nuse Monolog\\Logger;\n\nGlobalOptions::set([\n    'log' =\u003e [\n        'level' =\u003e Logger::DEBUG,\n    ],\n    'validation' =\u003e [\n        'method' =\u003e [\n            'arguments_count_only' =\u003e true,\n        ],\n    ],\n]);\n\n```\n\n### PHPJava の実行結果を出力する\n\n- 実行中のオペレーションの処理を確認したい場合は下記のとおりにします。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaClass;\nuse PHPJava\\Core\\Stream\\Reader\\FileReader;\n\n$javaClass = JavaClass::load('HelloWorld');\n\n$javaClass\n    -\u003egetInvoker()\n    -\u003egetStatic()\n    -\u003egetMethods()\n    -\u003ecall(\n        'main',\n        [\"Hello\", 'World']\n    );\n\n// デバッグトレースを表示します。\n$javaClass-\u003edebug();\n```\n\n- デバッグトレースを出力します。\n\n```\n[method]\npublic static void main(java.lang.String[])\n\n[code]\n\u003c0xb2\u003e \u003c0x00\u003e \u003c0x02\u003e \u003c0x2a\u003e \u003c0x03\u003e \u003c0x32\u003e \u003c0xb6\u003e \u003c0x00\u003e \u003c0x03\u003e \u003c0xb2\u003e \u003c0x00\u003e \u003c0x02\u003e \u003c0x2a\u003e \u003c0x04\u003e \u003c0x32\u003e \u003c0xb6\u003e \u003c0x00\u003e \u003c0x03\u003e \u003c0xb2\u003e \u003c0x00\u003e\n\u003c0x02\u003e \u003c0x2a\u003e \u003c0x05\u003e \u003c0x32\u003e \u003c0xb6\u003e \u003c0x00\u003e \u003c0x03\u003e \u003c0xb1\u003e\n\n[executed]\n      PC | OPCODE | MNEMONIC             | OPERANDS   | LOCAL STORAGE  \n---------+--------+----------------------+------------+-----------------\n       0 | 0xB2   | getstatic            | 0          | 1              \n       3 | 0x2A   | aload_0              | 1          | 1              \n       4 | 0x03   | iconst_0             | 2          | 1              \n       5 | 0x32   | aaload               | 3          | 1              \n       6 | 0xB6   | invokevirtual        | 2          | 1              \n       9 | 0xB2   | getstatic            | 0          | 1              \n      12 | 0x2A   | aload_0              | 1          | 1              \n      13 | 0x04   | iconst_1             | 2          | 1              \n      14 | 0x32   | aaload               | 3          | 1              \n      15 | 0xB6   | invokevirtual        | 2          | 1              \n      18 | 0xB2   | getstatic            | 0          | 1              \n      21 | 0x2A   | aload_0              | 1          | 1              \n      22 | 0x05   | iconst_2             | 2          | 1              \n      23 | 0x32   | aaload               | 3          | 1              \n      24 | 0xB6   | invokevirtual        | 2          | 1              \n      27 | 0xB1   | return               | 0          | 1              \n---------+--------+----------------------+------------+-----------------\n```\n\n- **[method]** は呼ばれたメソッドを表示します。\n- **[code]** は JVM 上の実際のコードを表示します。\n- **[executed]** は実行されたオペレーションコードの一覧を表示します。\n  - **PC** はプログラムカウンタを表示します。\n  - **OPCODE** はオペレーションコードを表示します。\n  - **MNEMONIC** はニーモニックを表示します。.\n  - **OPERANDS** はオペランドスタック上のアイテムを表示します。\n  - **LOCAL STORAGE** はローカルストレージに格納されているアイテムの数を表示します。\n\n\n## 大きな数字の計算について\n- PHP は通常、 Java における long 型や double 型といった大きな値の計算を行うことができません。\n  PHPJava ではそれらをカバーするために数値計算用ライブラリを使用します。\n  それらは、 下記の Java の型でラップされて使用されます。\n  そのため、数値をPHP側で取り扱う場合は、 string 型にキャストすることを推奨します。\n  また、通常の 64bit 版 PHP で計算できる範囲については、PHP の四則演算を使用して計算を行います。\n\n## Java の型\n- 下記はJava と PHPJava の型の比較表です。\n\n| Java | PHPJava |\n|:-----|:--------|\n| null | null |\n| boolean | \\PHPJava\\Kernel\\Types\\\\Boolean_  (`__toString` を含む) |\n| char | \\PHPJava\\Kernel\\Types\\\\Char_  (`__toString` を含む) |\n| byte | \\PHPJava\\Kernel\\Types\\\\Byte_  (`__toString` を含む) |\n| short | \\PHPJava\\Kernel\\Types\\\\Short_  (`__toString` を含む) |\n| int | \\PHPJava\\Kernel\\Types\\\\Int_  (`__toString` を含む) |\n| long | \\PHPJava\\Kernel\\Types\\\\Long_  (`__toString` を含む) |\n| float | \\PHPJava\\Kernel\\Types\\\\Float_  (`__toString` を含む) |\n| double | \\PHPJava\\Kernel\\Types\\\\Double_  (`__toString` を含む) |\n\n## Run Kotlin on the PHPJava\n## Kotlin を PHPJava で動かす。\nKotlin を PHPJava で動かしたいですか？\n可能ではありますが、現状は試験的な実装となっています。\n\n### クイックスタート\n\n1) Kotlin を書きます。\n\n```kotlin\nfun main(args: Array\u003cString\u003e) {\n    println(\"Hello World!\")\n}\n```\n\n2) ランタイム付きでコンパイルします。\n```\n$ kotlinc HelloWorld.kt -include-runtime -d HelloWorld.jar\n```\n\n3) Jar として実行します。\n\n```php\n\u003c?php\nuse PHPJava\\Core\\JavaArchive;\n\n$jar = new JavaArchive(__DIR__ . '/HelloWorld.jar');\n$jar-\u003eexecute([]);\n```\n\n`Hello World!` と出力されます。\n\n## ユニットテスト\n\n- PHPUnit でテストを動かします。\n```\n$ ./vendor/bin/phpunit tests/Cases\n```\n\n- コーディングルールをチェックします。\n\n```\n$ ./vendor/bin/phpcs --standard=phpcs.xml src\n```\n\n- すべてのテストを実行します。\n\n```\n$ composer run tests\n```\n\n## 参照\n- [Java Virtual Machine Specification](https://docs.oracle.com/javase/specs/jvms/se11/html/index.html)\n\n## ライセンス\nMIT\n","funding_links":[],"categories":["JVM实现"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphp-java%2Fphp-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphp-java%2Fphp-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphp-java%2Fphp-java/lists"}