aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-php-rpc/php/worker.php13
-rw-r--r--crates/shirabe-php-rpc/src/lib.rs40
-rw-r--r--crates/shirabe/src/platform/runtime.rs31
3 files changed, 73 insertions, 11 deletions
diff --git a/crates/shirabe-php-rpc/php/worker.php b/crates/shirabe-php-rpc/php/worker.php
index 58ba973..cb2bf48 100644
--- a/crates/shirabe-php-rpc/php/worker.php
+++ b/crates/shirabe-php-rpc/php/worker.php
@@ -9,6 +9,19 @@ if ($client === false) {
$dispatch = [
'defined' => static fn($name) => defined($name),
'constant' => static fn($name) => defined($name) ? constant($name) : null,
+ 'inet_pton' => static fn($arg) => @inet_pton($arg),
+ 'curl_version' => static fn($arg) => function_exists('curl_version') ? (curl_version()['version'] ?? null) : null,
+ 'phpversion' => static fn($name) => phpversion($name),
+ 'get_loaded_extensions' => static fn($arg) => implode(',', get_loaded_extensions()),
+ 'extension_info' => static function ($name) {
+ if (!extension_loaded($name)) {
+ return '';
+ }
+ $re = new ReflectionExtension($name);
+ ob_start();
+ $re->info();
+ return (string) ob_get_clean();
+ },
];
$read_exact = static function ($conn, int $len): ?string {
$buf = '';
diff --git a/crates/shirabe-php-rpc/src/lib.rs b/crates/shirabe-php-rpc/src/lib.rs
index 04583fa..3b0ee66 100644
--- a/crates/shirabe-php-rpc/src/lib.rs
+++ b/crates/shirabe-php-rpc/src/lib.rs
@@ -33,6 +33,46 @@ pub fn get_constant(name: &str) -> PhpMixed {
call("constant", name).unwrap_or(PhpMixed::Null)
}
+/// PHP `inet_pton($address)`.
+pub fn inet_pton(address: &str) -> PhpMixed {
+ call("inet_pton", address).unwrap_or(PhpMixed::Bool(false))
+}
+
+/// PHP `curl_version()['version']`.
+pub fn curl_version() -> Option<String> {
+ match call("curl_version", "") {
+ Some(PhpMixed::String(s)) => Some(s),
+ _ => None,
+ }
+}
+
+/// PHP `(new \ReflectionExtension($name))->info()` output.
+pub fn get_extension_info(name: &str) -> String {
+ match call("extension_info", name) {
+ Some(PhpMixed::String(s)) => s,
+ _ => String::new(),
+ }
+}
+
+/// PHP `phpversion($extension)`.
+pub fn phpversion(extension: &str) -> Option<String> {
+ match call("phpversion", extension) {
+ Some(PhpMixed::String(s)) => Some(s),
+ _ => None,
+ }
+}
+
+/// PHP `get_loaded_extensions()`.
+///
+/// Extension names are joined with `,` on the PHP side and split back here; real
+/// extension names never contain a comma.
+pub fn get_loaded_extensions() -> Vec<String> {
+ match call("get_loaded_extensions", "") {
+ Some(PhpMixed::String(s)) if !s.is_empty() => s.split(',').map(|s| s.to_string()).collect(),
+ _ => Vec::new(),
+ }
+}
+
const GLUE_SCRIPT: &str = include_str!("../php/worker.php");
struct Worker {
diff --git a/crates/shirabe/src/platform/runtime.rs b/crates/shirabe/src/platform/runtime.rs
index e4ff64a..4029790 100644
--- a/crates/shirabe/src/platform/runtime.rs
+++ b/crates/shirabe/src/platform/runtime.rs
@@ -3,8 +3,8 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
- PhpMixed, class_exists, function_exists, get_loaded_extensions, html_entity_decode, implode,
- instantiate_class, ltrim, phpversion, strip_tags, trim,
+ PhpMixed, class_exists, function_exists, html_entity_decode, implode, instantiate_class, ltrim,
+ strip_tags, trim,
};
/// Seam over the PHP runtime so PlatformRepository can be tested against mocked
@@ -44,9 +44,21 @@ impl RuntimeInterface for Runtime {
fn invoke(&self, callable: PhpMixed, arguments: Vec<PhpMixed>) -> PhpMixed {
// PHP: return $callable(...$arguments);
- // Dispatching an arbitrary PHP callable needs a PHP runtime; no shim exists.
- let _ = (callable, arguments);
- todo!()
+ // Only the specific dynamic callables PlatformRepository actually reaches are
+ // wired through php-rpc; arbitrary PHP callables are still unsupported.
+ match (&callable, arguments.as_slice()) {
+ (PhpMixed::String(name), [PhpMixed::String(arg)]) if name == "inet_pton" => {
+ shirabe_php_rpc::inet_pton(arg)
+ }
+ (PhpMixed::String(name), []) if name == "curl_version" => {
+ let mut version = IndexMap::new();
+ if let Some(v) = shirabe_php_rpc::curl_version() {
+ version.insert("version".to_string(), PhpMixed::String(v));
+ }
+ PhpMixed::Array(version)
+ }
+ _ => todo!(),
+ }
}
fn has_class(&self, class: &str) -> bool {
@@ -62,18 +74,15 @@ impl RuntimeInterface for Runtime {
}
fn get_extensions(&self) -> Vec<String> {
- get_loaded_extensions()
+ shirabe_php_rpc::get_loaded_extensions()
}
fn get_extension_version(&self, extension: &str) -> String {
- let version = phpversion(extension);
- version.unwrap_or_else(|| "0".to_string())
+ shirabe_php_rpc::phpversion(extension).unwrap_or_else(|| "0".to_string())
}
fn get_extension_info(&self, extension: &str) -> anyhow::Result<String> {
- // Depends on \ReflectionExtension::info() and output buffering; no shim equivalent exists.
- let _ = extension;
- todo!()
+ Ok(shirabe_php_rpc::get_extension_info(extension))
}
}