Created
April 20, 2017 13:12
-
-
Save Pamblam/3b6c60de61dc90d777c0221520c64fcd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Given a string of PHP code, this will provide a list of classes, their | |
* constructors and the line number they're on. Used for programmatically | |
* updating older code using PHP4 style constructors to PHP7 | |
*/ | |
class classParser{ | |
private $code; | |
private $tokens = array(); | |
public function __construct($code){ | |
$this->code = $code; | |
$this->getTokens(); | |
} | |
public function getClasses(){ | |
$classes = array(); | |
foreach($this->tokens as $ti=>$token){ | |
if(!is_array($token)) continue; | |
if($token['token'] === "T_CLASS"){ | |
$className = $this->getClassName($ti); | |
$const = $this->getConstructor($ti, $className); | |
$classes[] = array( | |
"name" => $className, | |
"constructor" => $const['name'], | |
"constructorLine" => $const['line'], | |
"signature_def" => $this->getConstructorSignatureWithVars($const['name'], $const['line']), | |
"signature_use" => $this->getConstructorSignature($const['name'], $const['line']) | |
); | |
} | |
} | |
return $classes; | |
} | |
private function getConstructorSignature($name, $line){ | |
$fullConstr = $this->getConstructorSignatureWithVars($name, $line); | |
$cParts = explode(",", trim($fullConstr, " ()")); | |
$varNames = array(); | |
foreach($cParts as $part){ | |
$var = explode("=", $part); | |
$varname = trim($var[0]); | |
if(substr($varname, 0, 1) !== "$") continue; | |
$varNames[] = trim($var[0]); | |
} | |
return "(".implode(", ", $varNames).")"; | |
} | |
private function getConstructorSignatureWithVars($name, $line){ | |
$lines = explode("\n", $this->code); | |
$startpos = strpos($lines[$line-1], $name) + strlen($name); | |
$endpos = strpos($lines[$line-1], ")")+1; | |
return substr($lines[$line-1], $startpos, $endpos-$startpos); | |
} | |
private function getTokens(){ | |
$tokens = token_get_all($this->code); | |
foreach($tokens as $k=>$v){ | |
if(is_array($v)){ | |
$this->tokens[] = array( | |
"token" => token_name($v[0]), | |
"string" => $v[1], | |
"line" => $v[2] | |
); | |
}else $this->tokens[] = $v; | |
} | |
} | |
private function getConstructor($tokenIndex, $classname){ | |
for($i=$tokenIndex+2; $i<count($this->tokens); $i++){ | |
if(!is_array($this->tokens[$i])) continue; | |
if($this->tokens[$i]['token'] === "T_CLASS") return false; | |
if(!is_array($this->tokens[$i])) continue; | |
if($this->tokens[$i]['token'] !== "T_FUNCTION") continue; | |
$constructorName = $this->getFunctName($i); | |
if(strtolower($constructorName) === strtolower($classname)) | |
return array('name'=>$constructorName, 'line'=>$this->tokens[$i]['line']); | |
if(strtolower($constructorName) === "__construct") | |
return array('name'=>$constructorName, 'line'=>$this->tokens[$i]['line']); | |
} | |
return false; | |
} | |
private function getFunctName($tokenIndex){ | |
if(empty($this->tokens[$tokenIndex])) return false; | |
if($this->tokens[$tokenIndex]['token'] !== "T_FUNCTION") return false; | |
if($this->tokens[$tokenIndex+1]['token'] !== "T_WHITESPACE") return false; | |
if($this->tokens[$tokenIndex+2]['token'] !== "T_STRING") return false; | |
return $this->tokens[$tokenIndex+2]['string']; | |
} | |
private function getClassName($tokenIndex){ | |
if(empty($this->tokens[$tokenIndex])) return false; | |
if($this->tokens[$tokenIndex]['token'] !== "T_CLASS") return false; | |
if($this->tokens[$tokenIndex+1]['token'] !== "T_WHITESPACE") return false; | |
if($this->tokens[$tokenIndex+2]['token'] !== "T_STRING") return false; | |
return $this->tokens[$tokenIndex+2]['string']; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment