Skip to content

Instantly share code, notes, and snippets.

@rica-carv
Forked from cgutierrez/FunctionBodyReflection.php
Created December 17, 2016 18:10
Show Gist options
  • Save rica-carv/3d162907455ed559e8b40b67368f9b31 to your computer and use it in GitHub Desktop.
Save rica-carv/3d162907455ed559e8b40b67368f9b31 to your computer and use it in GitHub Desktop.
Extension to ReflectionFunction for getting a functions body and character count.
<?php
class FunctionBodyReflection extends ReflectionFunction
{
/**
* get the body of a function as a string
*
* @access public
* @param bollean $withDeclaration true to return entire function delcaration
* @return String
*/
public function getBody($withDeclaration = true)
{
$totalparams = count($this->getParameters());
$source = file($this->getFilename(), FILE_IGNORE_NEW_LINES);
// set the indices that can be used to pull the function from the source file
$startindex = $this->getStartLine() - 1;
$endindex = $this->getEndline();
// get the body of the function from the source array
$funcbody = ($startindex == $endindex) ? $source[$startindex] :
trim(implode("\n", array_slice($source, $startindex, $endindex - $startindex)));
// the function body needs to be wrapped in php tags to be parsed as php by the tokenizer
$phpfuncbody = sprintf("<?php\n %s \n?>", $funcbody);
$body = array();
// define tokens that should be skipped if the whole declaration isn't needed
if (!$withDeclaration)
{
$skiptokens = array('T_FUNCTION', 'T_WHITESPACE', 'T_STRING', '(', ')');
// add variable tokens to account for the paramters in the function
for($i = 0; $i < $totalparams; $i++)
{
array_push($skiptokens, 'T_VARIABLE', ',');
}
}
// tokenize the function body and rebuild the function body as a string
// allows for the function to be formatted in any way
$tokens = token_get_all($phpfuncbody);
$totaltokens = count($tokens);
for($i = 0; $i < $totaltokens; $i++)
{
$token = $tokens[$i];
if (is_array($token))
{
list($tokenid, $tokenstr, $tokenline) = $token;
// skip open/close php tags
$tokenname = token_name($tokenid);
if ($tokenname == 'T_OPEN_TAG' || $tokenname == 'T_CLOSE_TAG') continue;
if (!isset($body[$tokenline])) $body[$tokenline] = "";
}
else
{
end($body);
$tokenid = null;
$lokenline = key($body);
$tokenstr = $tokenname = $token;
}
// skip declaration tokens if set to by the $withDeclaration param
if (!$withDeclaration && ($tokenkey = array_search($tokenname, $skiptokens)) !== false)
{
unset($skiptokens[$tokenkey]);
continue;
}
$body[$tokenline] .= $tokenstr;
}
// do some final body cleanup
return trim(implode("", $body), (!$withDeclaration) ? " \t\n\r\0\x0B{}" : " \t\n\r\0\x0B");
}
/**
* get the length of the body
*
* @access public
* @param boolean $countWhitespace true if whitespace should count against body size
* @return Integer
*/
public function getBodyLen($countWhitespace = true)
{
return strlen(($countWhitespace) ? $this->getBody(false) : preg_replace("/\s+/", "", $this->getBody(false)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment