首先概述一下JVM启动程序的过程:JVM在启动时传入的是类名,如java ClassName ,这样ClassName中的main方法就会被调用而执行,整个程序就跑起来了。
我们需要明白两点,一是传入类名后如何定位编译后的*.class文件;二是为什么main方法非要弄成static。
一、由java *.class文件的命名规则可知,*.class文件的名称和类名称相同,如果知道了类名就可以构造出*.class文件,这样文件就找到了。
二、static方法可以通过类名直接调用,也就是说可以在没有对象的情况下调用该方法,而JVM在调用main方法之前是不会创建该类对象的,所以只有把main方法弄成static,JVM才有可能调用该方法而使得程序运行起来。
基于这两点,我写了一个php模拟JVM的php启动器,这样我们就可以像写JAVA一样的创建php类了,代价只是在启动时多执行几十行代码。
这个就是启动器的代码,而我们可以创建一个JAVA风格的php类如下
执行的时候可以通过这样的命令在命令行下执行
php jvm.php HelloWorldDemo.php
或者跟上几个命令行参数,如下
php jvm.php HelloWorldDemo.php arg0 arg1 arg2
这些参数也会被传入main方法的$args参数中,该参数是数组类型
我们需要明白两点,一是传入类名后如何定位编译后的*.class文件;二是为什么main方法非要弄成static。
一、由java *.class文件的命名规则可知,*.class文件的名称和类名称相同,如果知道了类名就可以构造出*.class文件,这样文件就找到了。
二、static方法可以通过类名直接调用,也就是说可以在没有对象的情况下调用该方法,而JVM在调用main方法之前是不会创建该类对象的,所以只有把main方法弄成static,JVM才有可能调用该方法而使得程序运行起来。
基于这两点,我写了一个php模拟JVM的php启动器,这样我们就可以像写JAVA一样的创建php类了,代价只是在启动时多执行几十行代码。
require_once
(
'
./config.inc.php
'
);
print ( " " );
print ( " # PHP-JVM Framework [Version:{$cfg['app']['version']}] " );
print ( " " );
print ( " # Parsing Command-line Arguments... " );
$cmdArgs = $argv ;
$fullFileName = "" ;
$aArgs = array ();
$bIsArgs = false ;
foreach ( $cmdArgs as $arg ) {
$fileNameIdx = ereg ( ' .php$ ' , $arg );
if ( $fileNameIdx != false && $arg != $_SERVER [ ' PHP_SELF ' ]) {
$fullFileName = $arg ;
$bIsArgs = true ;
continue ;
}
if ( $bIsArgs ) {
array_push ( $aArgs , $arg );
}
}
$classNameEndIdx = strpos ( $fullFileName , ' . ' );
$className = substr ( $fullFileName , 0 , $classNameEndIdx );
// var_dump($fullFileName);
//var_dump($className);
//var_dump($aArgs);
print ( " # Parsing Command-line Arguments: Completed. " );
print ( " # File Name: {$fullFileName} " );
print ( " # Class Name: {$className} " );
print ( " " );
print ( " # Loading {$fullFileName}... " );
ob_start ();
if (( include $fullFileName ) == ' OK ' ) {
die ( " # !ERROR Cann't load file named {$fullFileName} " );
}
ob_end_clean ();
print ( " # Loading {$fullFileName}: Completed. " );
print ( " " );
print ( " # Calling Main Method of {$className}... " );
$sCodeStr = " {$className}::main($aArgs); " ;
print ( " # Running Main Method... " );
print ( " " );
eval ( $sCodeStr );
print ( " " );
print ( " " );
print ( " # Running Main Method: Completed. " );
print ( " " );
print ( " # PHP-JVM Framework [Version:{$cfg['app']['version']}] " );
print ( " " );
print ( " # Parsing Command-line Arguments... " );
$cmdArgs = $argv ;
$fullFileName = "" ;
$aArgs = array ();
$bIsArgs = false ;
foreach ( $cmdArgs as $arg ) {
$fileNameIdx = ereg ( ' .php$ ' , $arg );
if ( $fileNameIdx != false && $arg != $_SERVER [ ' PHP_SELF ' ]) {
$fullFileName = $arg ;
$bIsArgs = true ;
continue ;
}
if ( $bIsArgs ) {
array_push ( $aArgs , $arg );
}
}
$classNameEndIdx = strpos ( $fullFileName , ' . ' );
$className = substr ( $fullFileName , 0 , $classNameEndIdx );
// var_dump($fullFileName);
//var_dump($className);
//var_dump($aArgs);
print ( " # Parsing Command-line Arguments: Completed. " );
print ( " # File Name: {$fullFileName} " );
print ( " # Class Name: {$className} " );
print ( " " );
print ( " # Loading {$fullFileName}... " );
ob_start ();
if (( include $fullFileName ) == ' OK ' ) {
die ( " # !ERROR Cann't load file named {$fullFileName} " );
}
ob_end_clean ();
print ( " # Loading {$fullFileName}: Completed. " );
print ( " " );
print ( " # Calling Main Method of {$className}... " );
$sCodeStr = " {$className}::main($aArgs); " ;
print ( " # Running Main Method... " );
print ( " " );
eval ( $sCodeStr );
print ( " " );
print ( " " );
print ( " # Running Main Method: Completed. " );
这个就是启动器的代码,而我们可以创建一个JAVA风格的php类如下
class
HelloWorldDemo {
public function HelloWorldDemo() {
print ( " Hello World " );
}
public static function main( $args ) {
new HelloWorldDemo();
var_dump ( $args );
}
}
public function HelloWorldDemo() {
print ( " Hello World " );
}
public static function main( $args ) {
new HelloWorldDemo();
var_dump ( $args );
}
}
执行的时候可以通过这样的命令在命令行下执行
php jvm.php HelloWorldDemo.php
或者跟上几个命令行参数,如下
php jvm.php HelloWorldDemo.php arg0 arg1 arg2
这些参数也会被传入main方法的$args参数中,该参数是数组类型