コード例 #1
0
 /**
  * Returns whether this is an internal function
  *
  * @return boolean True if this is an internal function
  */
 public function isInternal()
 {
     if ($this->reflectionSource instanceof ReflectionFunction) {
         return $this->reflectionSource->isInternal();
     } else {
         return parent::isInternal();
     }
 }
コード例 #2
0
function dumpFuncInfo($name)
{
    $funcInfo = new ReflectionFunction($name);
    var_dump($funcInfo->getName());
    var_dump($funcInfo->isInternal());
    var_dump($funcInfo->isUserDefined());
    var_dump($funcInfo->getStartLine());
    var_dump($funcInfo->getEndLine());
    var_dump($funcInfo->getStaticVariables());
}
 /**
  * @param string $name
  * @return bool
  */
 protected function isInternalFunction($name)
 {
     try {
         $ref_func = new ReflectionFunction($name);
         return $ref_func->isInternal();
     } catch (ReflectionException $e) {
         // ReflectionException: Function xxx() does not exist
         return false;
     }
 }
コード例 #4
0
 private function isPhpFunction(Link $link)
 {
     $functionName = $link->getDestination();
     if (!$this->isMethodLink($functionName)) {
         return;
     }
     $functionName = substr($functionName, 0, -2);
     if (!function_exists($functionName)) {
         return false;
     }
     $functionReflection = new \ReflectionFunction($functionName);
     return $functionReflection->isInternal();
 }
コード例 #5
0
 protected function addFunctions($parent, array $functions)
 {
     if (!empty($functions['internal'])) {
         $functions = $functions['internal'];
     }
     foreach ($functions as $ref) {
         if (is_string($ref)) {
             $ref = new \ReflectionFunction($ref);
         }
         if (!$ref->isInternal()) {
             return;
         }
         $name = getFunctionString($ref);
         $this->append($parent, array($name, $ref));
     }
 }
コード例 #6
0
ファイル: ManagerTest.php プロジェクト: skeetr/skeetr
 public function testRegisterResetAndValues()
 {
     $this->assertFalse(Manager::overridden('natcasesort'));
     Manager::register('\\Skeetr\\Tests\\Runtime\\Example');
     $function = new \ReflectionFunction('natcasesort');
     $this->assertFalse($function->isInternal());
     $this->assertSame('foo', natcasesort('foo'));
     $this->assertTrue(Manager::overridden('natcasesort'));
     $this->assertSame(1, Example::$test);
     Example::$test = 0;
     Manager::reset();
     $this->assertSame(1, Example::$test);
     Example::$test = 0;
     Manager::reset('\\Skeetr\\Tests\\Runtime\\Example');
     $this->assertSame(1, Example::$test);
     $this->assertTrue(false === Manager::reset('NotExists'));
     $expected = array('example' => array('test' => 1));
     $this->assertSame($expected, Manager::values('\\Skeetr\\Tests\\Runtime\\Example'));
     $values = Manager::values('\\Skeetr\\Tests\\Runtime\\Example');
     $this->assertSame(1, $values['example']['test']);
 }
コード例 #7
0
 /**
  * @return string
  */
 private function ouptutUnusedFunctionsReport()
 {
     //prepare unused functions report
     $functions = get_defined_functions();
     $functions = array_filter($functions['user'], 'strtolower');
     $calledFunctions = array_filter($this->calledFunctions, 'strtolower');
     $deprecatedFunctions = array_filter(array_keys(code_review::getDeprecatedFunctionsList($this->maxVersion)), 'strtolower');
     $functions = array_diff($functions, $calledFunctions, $deprecatedFunctions);
     foreach ($functions as $key => $function) {
         if (function_exists($function)) {
             $reflectionFunction = new ReflectionFunction($function);
             if (!$reflectionFunction->isInternal()) {
                 continue;
             }
             unset($reflectionFunction);
         }
         unset($functions[$key]);
     }
     sort($functions);
     //unused functions report
     $result = "Not called but defined funcions:\n";
     $baseLenght = strlen(elgg_get_root_path());
     foreach (array_values($functions) as $functionName) {
         $reflectionFunction = new ReflectionFunction($functionName);
         $path = substr($reflectionFunction->getFileName(), $baseLenght);
         if (strpos($path, 'engine') !== 0) {
             continue;
         }
         $result .= "{$functionName} \t{$path}:{$reflectionFunction->getStartLine()}\n";
     }
     return $result;
 }
コード例 #8
0
ファイル: MicroPHP.php プロジェクト: licailing/licailing
 private static function checkRule($_rule, $val, $data, $db = null)
 {
     if (!$db) {
         $db = WoniuLoader::instance()->database();
     }
     $matches = self::getCheckRuleInfo($_rule);
     $_rule = $matches[1];
     $args = $matches[2];
     switch ($_rule) {
         case 'required':
             return !empty($val);
         case 'match':
             return isset($args[0]) && isset($data[$args[0]]) ? $val && $val == $data[$args[0]] : false;
         case 'equal':
             return isset($args[0]) ? $val && $val == $args[0] : false;
         case 'enum':
             return in_array($val, $args);
         case 'unique':
             #比如unique[user.name] , unique[user.name,id:1]
             if (!$val || !count($args)) {
                 return false;
             }
             $_info = explode('.', $args[0]);
             if (count($_info) != 2) {
                 return false;
             }
             $table = $_info[0];
             $col = $_info[1];
             if (isset($args[1])) {
                 $_id_info = explode(':', $args[1]);
                 if (count($_id_info) != 2) {
                     return false;
                 }
                 $id_col = $_id_info[0];
                 $id = $_id_info[1];
                 $id = stripos($id, '#') === 0 ? WoniuInput::get_post(substr($id, 1)) : $id;
                 $where = array($col => $val, "{$id_col} <>" => $id);
             } else {
                 $where = array($col => $val);
             }
             return !$db->where($where)->from($table)->count_all_results();
         case 'exists':
             #比如exists[user.name] , exists[user.name,type:1], exists[user.name,type:1,sex:#sex]
             if (!$val || !count($args)) {
                 return false;
             }
             $_info = explode('.', $args[0]);
             if (count($_info) != 2) {
                 return false;
             }
             $table = $_info[0];
             $col = $_info[1];
             $where = array($col => $val);
             if (count($args) > 1) {
                 foreach (array_slice($args, 1) as $v) {
                     $_id_info = explode(':', $v);
                     if (count($_id_info) != 2) {
                         continue;
                     }
                     $id_col = $_id_info[0];
                     $id = $_id_info[1];
                     $id = stripos($id, '#') === 0 ? WoniuInput::get_post(substr($id, 1)) : $id;
                     $where[$id_col] = $id;
                 }
             }
             return $db->where($where)->from($table)->count_all_results();
         case 'min_len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') >= intval($args[0]) : false;
         case 'max_len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') <= intval($args[0]) : false;
         case 'range_len':
             return count($args) == 2 ? mb_strlen($val, 'UTF-8') >= intval($args[0]) && mb_strlen($val, 'UTF-8') <= intval($args[1]) : false;
         case 'len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') == intval($args[0]) : false;
         case 'min':
             return isset($args[0]) && is_numeric($val) ? $val >= $args[0] : false;
         case 'max':
             return isset($args[0]) && is_numeric($val) ? $val <= $args[0] : false;
         case 'range':
             return count($args) == 2 && is_numeric($val) ? $val >= $args[0] && $val <= $args[1] : false;
         case 'alpha':
             #纯字母
             return !preg_match('/[^A-Za-z]+/', $val);
         case 'alpha_num':
             #纯字母和数字
             return !preg_match('/[^A-Za-z0-9]+/', $val);
         case 'alpha_dash':
             #纯字母和数字和下划线和-
             return !preg_match('/[^A-Za-z0-9_-]+/', $val);
         case 'alpha_start':
             #以字母开头
             return preg_match('/^[A-Za-z]+/', $val);
         case 'num':
             #纯数字
             return !preg_match('/[^0-9]+/', $val);
         case 'int':
             #整数
             return preg_match('/^([-+]?[1-9]\\d*|0)$/', $val);
         case 'float':
             #小数
             return preg_match('/^([1-9]\\d*|0)\\.\\d+$/', $val);
         case 'numeric':
             #数字-1,1.2,+3,4e5
             return is_numeric($val);
         case 'natural':
             #自然数0,1,2,3,12,333
             return preg_match('/^([1-9]\\d*|0)$/', $val);
         case 'natural_no_zero':
             #自然数不包含0
             return preg_match('/^[1-9]\\d*$/', $val);
         case 'email':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/', $val) : $args[0];
         case 'url':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^http[s]?:\\/\\/[A-Za-z0-9]+\\.[A-Za-z0-9]+[\\/=\\?%\\-&_~`@[\\]\':+!]*([^<>\\"])*$/', $val) : $args[0];
         case 'qq':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[1-9][0-9]{4,}$/', $val) : $args[0];
         case 'phone':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(?:\\d{3}-?\\d{8}|\\d{4}-?\\d{7})$/', $val) : $args[0];
         case 'mobile':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(14[0-9]{1}))+\\d{8})$/', $val) : $args[0];
         case 'zipcode':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[1-9]\\d{5}(?!\\d)$/', $val) : $args[0];
         case 'idcard':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^\\d{14}(\\d{4}|(\\d{3}[xX])|\\d{1})$/', $val) : $args[0];
         case 'ip':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/', $val) : $args[0];
         case 'chs':
             $count = implode(',', array_slice($args, 1, 2));
             $count = empty($count) ? '1,' : $count;
             $can_empty = isset($args[0]) && $args[0] == 'true';
             return !empty($val) ? preg_match('/^[\\x{4e00}-\\x{9fa5}]{' . $count . '}$/u', $val) : $can_empty;
         case 'date':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$/', $val) : $args[0];
         case 'time':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(([0-1][0-9])|([2][0-3])):([0-5][0-9])(:([0-5][0-9]))$/', $val) : $args[0];
         case 'datetime':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30))) (([0-1][0-9])|([2][0-3])):([0-5][0-9])(:([0-5][0-9]))$/', $val) : $args[0];
         case 'reg':
             #正则表达式验证,reg[/^[\]]$/i]
             /**
             * 模式修正符说明:
              i	表示在和模式进行匹配进不区分大小写
              m	将模式视为多行,使用^和$表示任何一行都可以以正则表达式开始或结束
              s	如果没有使用这个模式修正符号,元字符中的"."默认不能表示换行符号,将字符串视为单行
              x	表示模式中的空白忽略不计
              e	正则表达式必须使用在preg_replace替换字符串的函数中时才可以使用(讲这个函数时再说)
              A	以模式字符串开头,相当于元字符^
              Z	以模式字符串结尾,相当于元字符$
              U	正则表达式的特点:就是比较“贪婪”,使用该模式修正符可以取消贪婪模式
             */
             return !empty($args[0]) ? preg_match($args[0], $val) : false;
             /**
              * set set_post不参与验证,返回true跳过
              *
              * 说明:
              * set用于设置在验证数据前对数据进行处理的函数或者方法
              * set_post用于设置在验证数据后对数据进行处理的函数或者方法
              * 如果设置了set,数据在验证的时候验证的是处理过的数据
              * 如果设置了set_post,可以通过第三个参数$data接收数据:$this->checkData($rule, $_POST, $data),$data是验证通过并经过set_post处理后的数据
              * set和set_post后面是一个或者多个函数或者方法,多个逗号分割
              * 注意:
              * 1.无论是函数或者方法都必须有一个字符串返回
              * 2.如果是系统函数,系统会传递当前值给系统函数,因此系统函数必须是至少接受一个字符串参数,比如md5,trim
              * 3.如果是自定义的函数,系统会传递当前值和全部数据给自定义的函数,因此自定义函数可以接收两个参数第一个是值,第二个是全部数据$data
              * 4.如果是类的方法写法是:类名称::方法名 (方法静态动态都可以,public,private,都可以)
              */
         /**
          * set set_post不参与验证,返回true跳过
          *
          * 说明:
          * set用于设置在验证数据前对数据进行处理的函数或者方法
          * set_post用于设置在验证数据后对数据进行处理的函数或者方法
          * 如果设置了set,数据在验证的时候验证的是处理过的数据
          * 如果设置了set_post,可以通过第三个参数$data接收数据:$this->checkData($rule, $_POST, $data),$data是验证通过并经过set_post处理后的数据
          * set和set_post后面是一个或者多个函数或者方法,多个逗号分割
          * 注意:
          * 1.无论是函数或者方法都必须有一个字符串返回
          * 2.如果是系统函数,系统会传递当前值给系统函数,因此系统函数必须是至少接受一个字符串参数,比如md5,trim
          * 3.如果是自定义的函数,系统会传递当前值和全部数据给自定义的函数,因此自定义函数可以接收两个参数第一个是值,第二个是全部数据$data
          * 4.如果是类的方法写法是:类名称::方法名 (方法静态动态都可以,public,private,都可以)
          */
         case 'set':
         case 'set_post':
             return true;
         default:
             $_args = array_merge(array($val, $data), $args);
             $matches = self::getCheckRuleInfo($_rule);
             $func = $matches[1];
             $args = $matches[2];
             if (function_exists($func)) {
                 $reflection = new ReflectionFunction($func);
                 //如果是系统函数
                 if ($reflection->isInternal()) {
                     $_args = isset($_args[0]) ? array($_args[0]) : array();
                 }
             }
             return self::callFunc($_rule, $_args);
     }
     return false;
 }
コード例 #9
0
ファイル: bootstrap.php プロジェクト: DQNEO/prestissimo
    $funcs = get_defined_functions();
    foreach ($funcs['internal'] as $func) {
        $rf = new ReflectionFunction($func);
        $info = array('kind' => 'f', 'namespace' => $rf->getNamespaceName());
        $params = array();
        foreach ($rf->getParameters() as $rp) {
            $class = '';
            if (!defined('HHVM_VERSION')) {
                $class = $rp->getClass();
            }
            $param = '';
            if ($class) {
                $param = $class->getName() . ' ';
            } elseif ($rp->isArray()) {
                $param = 'array ';
            }
            $param .= '$' . $rp->getName();
            if ($rp->isOptional() && $rf->isUserDefined()) {
                $param .= '=' . json_encode($rp->getDefaultValue());
            }
            $params[] = $param;
        }
        $info['type'] = '(' . implode(', ', $params) . ')';
        if ($rf->isInternal()) {
            $filename = '(ext-' . $rf->getExtensionName() . ')';
        } else {
            $filename = str_replace($base, '', $rf->getFileName());
        }
        fwrite($fp, implode("\t", array($rf->getName(), $filename, $rf->getStartLine() . ';"', '')) . $build($info) . PHP_EOL);
    }
});
コード例 #10
0
<pre>
<?php 
function sayHello($name, $h)
{
    static $count = 0;
    return "<h{$h}>Hello, {$name}</h{$h}>";
}
// Обзор функции
Reflection::export(new ReflectionFunction('sayHello'));
// Создание экземпляра класса ReflectionFunction
$func = new ReflectionFunction('sayHello');
// Вывод основной информации
printf("<p>===> %s функция '%s'\n" . "     объявлена в %s\n" . "     строки с %d по %d\n", $func->isInternal() ? 'Internal' : 'User-defined', $func->getName(), $func->getFileName(), $func->getStartLine(), $func->getEndline());
// Вывод статических переменных, если они есть
if ($statics = $func->getStaticVariables()) {
    printf("<p>---> Статическая переменная: %s\n", var_export($statics, 1));
}
// Вызов функции
printf("<p>---> Результат вызова: ");
$result = $func->invoke("John", "1");
echo $result;
?>
</pre>
コード例 #11
0
ファイル: 025.php プロジェクト: badlamer/hhvm
<?php

/**
hoho
*/
function test($a, $b = 1, $c = "")
{
    static $var = 1;
}
$func = new ReflectionFunction("test");
var_dump($func->export("test"));
echo "--getName--\n";
var_dump($func->getName());
echo "--isInternal--\n";
var_dump($func->isInternal());
echo "--isUserDefined--\n";
var_dump($func->isUserDefined());
echo "--getFilename--\n";
var_dump($func->getFilename());
echo "--getStartline--\n";
var_dump($func->getStartline());
echo "--getEndline--\n";
var_dump($func->getEndline());
echo "--getDocComment--\n";
var_dump($func->getDocComment());
echo "--getStaticVariables--\n";
var_dump($func->getStaticVariables());
echo "--invoke--\n";
var_dump($func->invoke(array(1, 2, 3)));
echo "--invokeArgs--\n";
var_dump($func->invokeArgs(array(1, 2, 3)));
コード例 #12
0
ファイル: class.jbdump.php プロジェクト: CB9TOIIIA/JBDump
 /**
  * Get all info about function
  * @param   string|function $functionName Function or function name
  * @return  array|bool
  */
 protected static function _getFunction($functionName)
 {
     if (is_string($functionName) && !function_exists($functionName)) {
         return false;
     } elseif (empty($functionName)) {
         return false;
     }
     // create ReflectionFunction instance
     $func = new ReflectionFunction($functionName);
     // get basic function info
     $result = array();
     $result['name'] = $func->getName();
     $result['type'] = $func->isInternal() ? 'internal' : 'user-defined';
     if (method_exists($func, 'getNamespaceName') && ($namespace = $func->getNamespaceName())) {
         $result['namespace'] = $namespace;
     }
     if ($func->isDeprecated()) {
         $result['deprecated'] = true;
     }
     if ($static = $func->getStaticVariables()) {
         $result['static'] = $static;
     }
     if ($reference = $func->returnsReference()) {
         $result['reference'] = $reference;
     }
     if ($path = $func->getFileName()) {
         $result['path'] = $path . ' ' . $func->getStartLine() . '/' . $func->getEndLine();
     }
     if ($parameters = $func->getParameters()) {
         $result['parameters'] = self::_getParams($parameters, $func->isInternal());
     }
     // get function source
     if (isset($result['path']) && $result['path']) {
         $result['comment'] = $func->getDocComment();
         $startLine = $func->getStartLine();
         $endLine = $func->getEndLine();
         $source = @file($func->getFileName());
         if ($startLine && $source) {
             $from = (int) ($startLine - 1);
             $to = (int) ($endLine - $startLine + 1);
             $slice = array_slice($source, $from, $to);
             $result['source::source'] = implode('', $slice);
         }
     }
     return $result;
 }
コード例 #13
0
/**
 * Given a user-defined PHP function, create a PHP 'wrapper' function that can
 * be exposed as xmlrpc method from an xmlrpc_server object and called from remote
 * clients (as well as its corresponding signature info).
 *
 * Since php is a typeless language, to infer types of input and output parameters,
 * it relies on parsing the javadoc-style comment block associated with the given
 * function. Usage of xmlrpc native types (such as datetime.dateTime.iso8601 and base64)
 * in the @param tag is also allowed, if you need the php function to receive/send
 * data in that particular format (note that base64 encoding/decoding is transparently
 * carried out by the lib, while datetime vals are passed around as strings)
 *
 * Known limitations:
 * - requires PHP 5.0.3 +
 * - only works for user-defined functions, not for PHP internal functions
 *   (reflection does not support retrieving number/type of params for those)
 * - functions returning php objects will generate special xmlrpc responses:
 *   when the xmlrpc decoding of those responses is carried out by this same lib, using
 *   the appropriate param in php_xmlrpc_decode, the php objects will be rebuilt.
 *   In short: php objects can be serialized, too (except for their resource members),
 *   using this function.
 *   Other libs might choke on the very same xml that will be generated in this case
 *   (i.e. it has a nonstandard attribute on struct element tags)
 * - usage of javadoc @param tags using param names in a different order from the
 *   function prototype is not considered valid (to be fixed?)
 *
 * Note that since rel. 2.0RC3 the preferred method to have the server call 'standard'
 * php functions (ie. functions not expecting a single xmlrpcmsg obj as parameter)
 * is by making use of the functions_parameters_type class member.
 *
 * @param string $funcname the name of the PHP user function to be exposed as xmlrpc method; array($obj, 'methodname') and array('class', 'methodname') are ok too
 * @param string $newfuncname (optional) name for function to be created
 * @param array $extra_options (optional) array of options for conversion. valid values include:
 *        bool  return_source when true, php code w. function definition will be returned, not evaluated
 *        bool  encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
 *        bool  decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
 *        bool  suppress_warnings  remove from produced xml any runtime warnings due to the php function being invoked
 * @return false on error, or an array containing the name of the new php function,
 *         its signature and docs, to be used in the server dispatch map
 *
 * @todo decide how to deal with params passed by ref: bomb out or allow?
 * @todo finish using javadoc info to build method sig if all params are named but out of order
 * @todo add a check for params of 'resource' type
 * @todo add some trigger_errors / error_log when returning false?
 * @todo what to do when the PHP function returns NULL? we are currently returning an empty string value...
 * @todo add an option to suppress php warnings in invocation of user function, similar to server debug level 3?
 * @todo if $newfuncname is empty, we could use create_user_func instead of eval, as it is possibly faster
 * @todo add a verbatim_object_copy parameter to allow avoiding the same obj instance?
 */
function wrap_php_function($funcname, $newfuncname = '', $extra_options = array())
{
    $buildit = isset($extra_options['return_source']) ? !$extra_options['return_source'] : true;
    $prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
    $encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool) $extra_options['encode_php_objs'] : false;
    $decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool) $extra_options['decode_php_objs'] : false;
    $catch_warnings = isset($extra_options['suppress_warnings']) && $extra_options['suppress_warnings'] ? '@' : '';
    if (version_compare(phpversion(), '5.0.3') == -1) {
        // up to php 5.0.3 some useful reflection methods were missing
        error_log('XML-RPC: cannot not wrap php functions unless running php version bigger than 5.0.3');
        return false;
    }
    $exists = false;
    if (is_string($funcname) && strpos($funcname, '::') !== false) {
        $funcname = explode('::', $funcname);
    }
    if (is_array($funcname)) {
        if (count($funcname) < 2 || !is_string($funcname[0]) && !is_object($funcname[0])) {
            error_log('XML-RPC: syntax for function to be wrapped is wrong');
            return false;
        }
        if (is_string($funcname[0])) {
            $plainfuncname = implode('::', $funcname);
        } elseif (is_object($funcname[0])) {
            $plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];
        }
        $exists = method_exists($funcname[0], $funcname[1]);
        if (!$exists && version_compare(phpversion(), '5.1') < 0) {
            // workaround for php 5.0: static class methods are not seen by method_exists
            $exists = is_callable($funcname);
        }
    } else {
        $plainfuncname = $funcname;
        $exists = function_exists($funcname);
    }
    if (!$exists) {
        error_log('XML-RPC: function to be wrapped is not defined: ' . $plainfuncname);
        return false;
    } else {
        // determine name of new php function
        if ($newfuncname == '') {
            if (is_array($funcname)) {
                if (is_string($funcname[0])) {
                    $xmlrpcfuncname = "{$prefix}_" . implode('_', $funcname);
                } else {
                    $xmlrpcfuncname = "{$prefix}_" . get_class($funcname[0]) . '_' . $funcname[1];
                }
            } else {
                $xmlrpcfuncname = "{$prefix}_{$funcname}";
            }
        } else {
            $xmlrpcfuncname = $newfuncname;
        }
        while ($buildit && function_exists($xmlrpcfuncname)) {
            $xmlrpcfuncname .= 'x';
        }
        // start to introspect PHP code
        if (is_array($funcname)) {
            $func = new ReflectionMethod($funcname[0], $funcname[1]);
            if ($func->isPrivate()) {
                error_log('XML-RPC: method to be wrapped is private: ' . $plainfuncname);
                return false;
            }
            if ($func->isProtected()) {
                error_log('XML-RPC: method to be wrapped is protected: ' . $plainfuncname);
                return false;
            }
            if ($func->isConstructor()) {
                error_log('XML-RPC: method to be wrapped is the constructor: ' . $plainfuncname);
                return false;
            }
            // php 503 always says isdestructor = true...
            if (version_compare(phpversion(), '5.0.3') != 0 && $func->isDestructor()) {
                error_log('XML-RPC: method to be wrapped is the destructor: ' . $plainfuncname);
                return false;
            }
            if ($func->isAbstract()) {
                error_log('XML-RPC: method to be wrapped is abstract: ' . $plainfuncname);
                return false;
            }
            /// @todo add more checks for static vs. nonstatic?
        } else {
            $func = new ReflectionFunction($funcname);
        }
        if ($func->isInternal()) {
            // Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
            // instead of getparameters to fully reflect internal php functions ?
            error_log('XML-RPC: function to be wrapped is internal: ' . $plainfuncname);
            return false;
        }
        // retrieve parameter names, types and description from javadoc comments
        // function description
        $desc = '';
        // type of return val: by default 'any'
        $returns = $GLOBALS['xmlrpcValue'];
        // desc of return val
        $returnsDocs = '';
        // type + name of function parameters
        $paramDocs = array();
        $docs = $func->getDocComment();
        if ($docs != '') {
            $docs = explode("\n", $docs);
            $i = 0;
            foreach ($docs as $doc) {
                $doc = trim($doc, " \r\t/*");
                if (strlen($doc) && strpos($doc, '@') !== 0 && !$i) {
                    if ($desc) {
                        $desc .= "\n";
                    }
                    $desc .= $doc;
                } elseif (strpos($doc, '@param') === 0) {
                    // syntax: @param type [$name] desc
                    if (preg_match('/@param\\s+(\\S+)(\\s+\\$\\S+)?\\s+(.+)/', $doc, $matches)) {
                        if (strpos($matches[1], '|')) {
                            //$paramDocs[$i]['type'] = explode('|', $matches[1]);
                            $paramDocs[$i]['type'] = 'mixed';
                        } else {
                            $paramDocs[$i]['type'] = $matches[1];
                        }
                        $paramDocs[$i]['name'] = trim($matches[2]);
                        $paramDocs[$i]['doc'] = $matches[3];
                    }
                    $i++;
                } elseif (strpos($doc, '@return') === 0) {
                    // syntax: @return type desc
                    //$returns = preg_split('/\s+/', $doc);
                    if (preg_match('/@return\\s+(\\S+)\\s+(.+)/', $doc, $matches)) {
                        $returns = php_2_xmlrpc_type($matches[1]);
                        if (isset($matches[2])) {
                            $returnsDocs = $matches[2];
                        }
                    }
                }
            }
        }
        // execute introspection of actual function prototype
        $params = array();
        $i = 0;
        foreach ($func->getParameters() as $paramobj) {
            $params[$i] = array();
            $params[$i]['name'] = '$' . $paramobj->getName();
            $params[$i]['isoptional'] = $paramobj->isOptional();
            $i++;
        }
        // start  building of PHP code to be eval'd
        $innercode = '';
        $i = 0;
        $parsvariations = array();
        $pars = array();
        $pnum = count($params);
        foreach ($params as $param) {
            if (isset($paramDocs[$i]['name']) && $paramDocs[$i]['name'] && strtolower($paramDocs[$i]['name']) != strtolower($param['name'])) {
                // param name from phpdoc info does not match param definition!
                $paramDocs[$i]['type'] = 'mixed';
            }
            if ($param['isoptional']) {
                // this particular parameter is optional. save as valid previous list of parameters
                $innercode .= "if (\$paramcount > {$i}) {\n";
                $parsvariations[] = $pars;
            }
            $innercode .= "\$p{$i} = \$msg->getParam({$i});\n";
            if ($decode_php_objects) {
                $innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p{$i} = \$p{$i}->scalarval(); else \$p{$i} = php_{$prefix}_decode(\$p{$i}, array('decode_php_objs'));\n";
            } else {
                $innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p{$i} = \$p{$i}->scalarval(); else \$p{$i} = php_{$prefix}_decode(\$p{$i});\n";
            }
            $pars[] = "\$p{$i}";
            $i++;
            if ($param['isoptional']) {
                $innercode .= "}\n";
            }
            if ($i == $pnum) {
                // last allowed parameters combination
                $parsvariations[] = $pars;
            }
        }
        $sigs = array();
        $psigs = array();
        if (count($parsvariations) == 0) {
            // only known good synopsis = no parameters
            $parsvariations[] = array();
            $minpars = 0;
        } else {
            $minpars = count($parsvariations[0]);
        }
        if ($minpars) {
            // add to code the check for min params number
            // NB: this check needs to be done BEFORE decoding param values
            $innercode = "\$paramcount = \$msg->getNumParams();\n" . "if (\$paramcount < {$minpars}) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n" . $innercode;
        } else {
            $innercode = "\$paramcount = \$msg->getNumParams();\n" . $innercode;
        }
        $innercode .= "\$np = false;\n";
        // since there are no closures in php, if we are given an object instance,
        // we store a pointer to it in a global var...
        if (is_array($funcname) && is_object($funcname[0])) {
            $GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];
            $innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['{$xmlrpcfuncname}'];\n";
            $realfuncname = '$obj->' . $funcname[1];
        } else {
            $realfuncname = $plainfuncname;
        }
        foreach ($parsvariations as $pars) {
            $innercode .= "if (\$paramcount == " . count($pars) . ") \$retval = {$catch_warnings}{$realfuncname}(" . implode(',', $pars) . "); else\n";
            // build a 'generic' signature (only use an appropriate return type)
            $sig = array($returns);
            $psig = array($returnsDocs);
            for ($i = 0; $i < count($pars); $i++) {
                if (isset($paramDocs[$i]['type'])) {
                    $sig[] = php_2_xmlrpc_type($paramDocs[$i]['type']);
                } else {
                    $sig[] = $GLOBALS['xmlrpcValue'];
                }
                $psig[] = isset($paramDocs[$i]['doc']) ? $paramDocs[$i]['doc'] : '';
            }
            $sigs[] = $sig;
            $psigs[] = $psig;
        }
        $innercode .= "\$np = true;\n";
        $innercode .= "if (\$np) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}'); else {\n";
        //$innercode .= "if (\$_xmlrpcs_error_occurred) return new xmlrpcresp(0, $GLOBALS['xmlrpcerr']user, \$_xmlrpcs_error_occurred); else\n";
        $innercode .= "if (is_a(\$retval, '{$prefix}resp')) return \$retval; else\n";
        if ($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64']) {
            $innercode .= "return new {$prefix}resp(new {$prefix}val(\$retval, '{$returns}'));";
        } else {
            if ($encode_php_objects) {
                $innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval, array('encode_php_objs')));\n";
            } else {
                $innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval));\n";
            }
        }
        // shall we exclude functions returning by ref?
        // if($func->returnsReference())
        // 	return false;
        $code = "function {$xmlrpcfuncname}(\$msg) {\n" . $innercode . "}\n}";
        //print_r($code);
        if ($buildit) {
            $allOK = 0;
            eval($code . '$allOK=1;');
            // alternative
            //$xmlrpcfuncname = create_function('$m', $innercode);
            if (!$allOK) {
                error_log('XML-RPC: could not create function ' . $xmlrpcfuncname . ' to wrap php function ' . $plainfuncname);
                return false;
            }
        }
        /// @todo examine if $paramDocs matches $parsvariations and build array for
        /// usage as method signature, plus put together a nice string for docs
        $ret = array('function' => $xmlrpcfuncname, 'signature' => $sigs, 'docstring' => $desc, 'signature_docs' => $psigs, 'source' => $code);
        return $ret;
    }
}
コード例 #14
0
 /**
  * Shows a backtrace item.
  *
  * @param int   $n     Count.
  * @param array $trace Trace result.
  *
  * @return void
  */
 protected function _showTraceItem($n, $trace)
 {
     echo '<tr><td align="right" valign="top" class="error-number">#', $n, '</td><td>';
     if (isset($trace['class'])) {
         if (preg_match('/^Phalcon/', $trace['class'])) {
             echo '<span class="error-class"><a target="_new" href="http://docs.phalconphp.com/en/latest/api/', str_replace('\\', '_', $trace['class']), '.html">', $trace['class'], '</a></span>';
         } else {
             $classReflection = new \ReflectionClass($trace['class']);
             if ($classReflection->isInternal()) {
                 echo '<span class="error-class"><a target="_new" href="http://php.net/manual/en/class.', str_replace('_', '-', strtolower($trace['class'])), '.php">', $trace['class'], '</a></span>';
             } else {
                 echo '<span class="error-class">', $trace['class'], '</span>';
             }
         }
         echo $trace['type'];
     }
     if (isset($trace['class'])) {
         echo '<span class="error-function">', $trace['function'], '</span>';
     } else {
         if (function_exists($trace['function'])) {
             $functionReflection = new \ReflectionFunction($trace['function']);
             if ($functionReflection->isInternal()) {
                 echo '<span class="error-function"><a target="_new" href="http://php.net/manual/en/function.', str_replace('_', '-', $trace['function']), '.php">', $trace['function'], '</a></span>';
             } else {
                 echo '<span class="error-function">', $trace['function'], '</span>';
             }
         } else {
             echo '<span class="error-function">', $trace['function'], '</span>';
         }
     }
     if (isset($trace['args'])) {
         $this->_echoArgs($trace['args']);
     }
     if (isset($trace['file'])) {
         echo '<br/><span class="error-file">', $trace['file'], ' (', $trace['line'], ')</span>';
     }
     echo '</td></tr>';
     if ($this->_showFiles) {
         if (isset($trace['file'])) {
             $this->_echoFile($trace['file'], $trace['line']);
         }
     }
 }
コード例 #15
0
ファイル: Smd.php プロジェクト: xamiro-dev/xamiro
 /**
  * maps function and all parameters of function using reflection. returns object map
  * as object throws error if mapping was not successful
  *
  * @error 14105
  * @param string $function expects function name
  * @return null|XO
  * @throws Xapp_Rpc_Smd_Exception
  */
 protected function mapFunction($function)
 {
     try {
         $tmp = array();
         $obj = new XO();
         $function = new ReflectionFunction($function);
         if ($function->isInternal()) {
             throw new Xapp_Rpc_Smd_Exception(xapp_sprintf(_("function: %s can not be mapped since it is internal"), $function), 1410502);
         }
         $obj->transport = null;
         $obj->target = null;
         $method = $this->mapMethod($function);
         if (xapp_get_option(self::SERVICE_DESCRIPTION, $this) && isset($method->description)) {
             $obj->description = $method->description;
         }
         if (isset($method->returns)) {
             $obj->returns = $method->returns;
         }
         $i = 0;
         foreach ($function->getParameters() as $p) {
             $params = $this->mapParameter($p);
             if (isset($method->params) && isset($method->params['type'][$i])) {
                 $params->type = $method->params['type'][$i];
             }
             if (isset($method->params) && isset($method->params['description'][$i]) && xapp_get_option(self::SERVICE_DESCRIPTION, $this)) {
                 $params->description = $method->params['description'][$i];
             }
             $tmp[] = $params;
             $i++;
         }
         $obj->parameters = $tmp;
         return $obj;
     } catch (ReflectionException $e) {
         throw new Xapp_Rpc_Smd_Exception(xapp_sprintf(_("unable to map function: %s due to reflection error: %d, %s"), $function, $e->getCode(), $e->getMessage()), 1410501);
     }
 }
コード例 #16
0
/**
 * ensures that the given callable is really callable
 *
 * Internal functions like strlen() or is_string() require an *exact* amount
 * of arguments. If they receive too many arguments they just report an error.
 * This is a problem when you pass such a function as callable to a place
 * where it will receive more than it's exact amount of arguments.
 *
 * @param   callable  $callable
 * @return  callable
 * @since   4.0.0
 */
function ensureCallable(callable $callable) : callable
{
    if (!is_string($callable)) {
        return $callable;
    }
    static $wrappedFunctions = [];
    if (isset($wrappedFunctions[$callable])) {
        return $wrappedFunctions[$callable];
    }
    $function = new \ReflectionFunction($callable);
    if (!$function->isInternal()) {
        return $callable;
    }
    $signature = $arguments = '';
    foreach ($function->getParameters() as $position => $param) {
        $signature .= ', ' . ($param->isPassedByReference() ? '&' : '') . '$_' . $position . ($param->isOptional() ? '= null' : '');
        $arguments .= ', $_' . $position;
    }
    $wrappedFunctions[$callable] = eval('return function(' . substr($signature, 2) . ') { return ' . $callable . '(' . substr($arguments, 2) . '); };');
    return $wrappedFunctions[$callable];
}
コード例 #17
0
ファイル: MicroPHP.min.php プロジェクト: cenxun/microphp
 private static function checkRule($_rule, $val, $data, $db = null)
 {
     if (!$db) {
         $db = MpLoader::instance()->database();
     }
     $matches = self::getCheckRuleInfo($_rule);
     $_rule = $matches[1];
     $args = $matches[2];
     switch ($_rule) {
         case 'required':
             return !empty($val);
         case 'match':
             return isset($args[0]) && isset($data[$args[0]]) ? $val && $val == $data[$args[0]] : false;
         case 'equal':
             return isset($args[0]) ? $val && $val == $args[0] : false;
         case 'enum':
             return in_array($val, $args);
         case 'unique':
             if (!$val || !count($args)) {
                 return false;
             }
             $_info = explode('.', $args[0]);
             if (count($_info) != 2) {
                 return false;
             }
             $table = $_info[0];
             $col = $_info[1];
             if (isset($args[1])) {
                 $_id_info = explode(':', $args[1]);
                 if (count($_id_info) != 2) {
                     return false;
                 }
                 $id_col = $_id_info[0];
                 $id = $_id_info[1];
                 $id = stripos($id, '#') === 0 ? MpInput::get_post(substr($id, 1)) : $id;
                 $where = array($col => $val, "{$id_col} <>" => $id);
             } else {
                 $where = array($col => $val);
             }
             return !$db->where($where)->from($table)->count_all_results();
         case 'exists':
             if (!$val || !count($args)) {
                 return false;
             }
             $_info = explode('.', $args[0]);
             if (count($_info) != 2) {
                 return false;
             }
             $table = $_info[0];
             $col = $_info[1];
             $where = array($col => $val);
             if (count($args) > 1) {
                 foreach (array_slice($args, 1) as $v) {
                     $_id_info = explode(':', $v);
                     if (count($_id_info) != 2) {
                         continue;
                     }
                     $id_col = $_id_info[0];
                     $id = $_id_info[1];
                     $id = stripos($id, '#') === 0 ? MpInput::get_post(substr($id, 1)) : $id;
                     $where[$id_col] = $id;
                 }
             }
             return $db->where($where)->from($table)->count_all_results();
         case 'min_len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') >= intval($args[0]) : false;
         case 'max_len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') <= intval($args[0]) : false;
         case 'range_len':
             return count($args) == 2 ? mb_strlen($val, 'UTF-8') >= intval($args[0]) && mb_strlen($val, 'UTF-8') <= intval($args[1]) : false;
         case 'len':
             return isset($args[0]) ? mb_strlen($val, 'UTF-8') == intval($args[0]) : false;
         case 'min':
             return isset($args[0]) && is_numeric($val) ? $val >= $args[0] : false;
         case 'max':
             return isset($args[0]) && is_numeric($val) ? $val <= $args[0] : false;
         case 'range':
             return count($args) == 2 && is_numeric($val) ? $val >= $args[0] && $val <= $args[1] : false;
         case 'alpha':
             return !preg_match('/[^A-Za-z]+/', $val);
         case 'alpha_num':
             return !preg_match('/[^A-Za-z0-9]+/', $val);
         case 'alpha_dash':
             return !preg_match('/[^A-Za-z0-9_-]+/', $val);
         case 'alpha_start':
             return preg_match('/^[A-Za-z]+/', $val);
         case 'num':
             return !preg_match('/[^0-9]+/', $val);
         case 'int':
             return preg_match('/^([-+]?[1-9]\\d*|0)$/', $val);
         case 'float':
             return preg_match('/^([1-9]\\d*|0)\\.\\d+$/', $val);
         case 'numeric':
             return is_numeric($val);
         case 'natural':
             return preg_match('/^([1-9]\\d*|0)$/', $val);
         case 'natural_no_zero':
             return preg_match('/^[1-9]\\d*$/', $val);
         case 'email':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/', $val) : $args[0];
         case 'url':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^http[s]?:\\/\\/[A-Za-z0-9]+\\.[A-Za-z0-9]+[\\/=\\?%\\-&_~`@[\\]\':+!]*([^<>\\"])*$/', $val) : $args[0];
         case 'qq':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[1-9][0-9]{4,}$/', $val) : $args[0];
         case 'phone':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(?:\\d{3}-?\\d{8}|\\d{4}-?\\d{7})$/', $val) : $args[0];
         case 'mobile':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(14[0-9]{1}))+\\d{8})$/', $val) : $args[0];
         case 'zipcode':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[1-9]\\d{5}(?!\\d)$/', $val) : $args[0];
         case 'idcard':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^\\d{14}(\\d{4}|(\\d{3}[xX])|\\d{1})$/', $val) : $args[0];
         case 'ip':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/', $val) : $args[0];
         case 'chs':
             $count = implode(',', array_slice($args, 1, 2));
             $count = empty($count) ? '1,' : $count;
             $can_empty = isset($args[0]) && $args[0] == 'true';
             return !empty($val) ? preg_match('/^[\\x{4e00}-\\x{9fa5}]{' . $count . '}$/u', $val) : $can_empty;
         case 'date':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$/', $val) : $args[0];
         case 'time':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^(([0-1][0-9])|([2][0-3])):([0-5][0-9])(:([0-5][0-9]))$/', $val) : $args[0];
         case 'datetime':
             $args[0] = isset($args[0]) && $args[0] == 'true' ? TRUE : false;
             return !empty($val) ? preg_match('/^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30))) (([0-1][0-9])|([2][0-3])):([0-5][0-9])(:([0-5][0-9]))$/', $val) : $args[0];
         case 'reg':
             return !empty($args[0]) ? preg_match($args[0], $val) : false;
         case 'set':
         case 'set_post':
             return true;
         default:
             $_args = array_merge(array($val, $data), $args);
             $matches = self::getCheckRuleInfo($_rule);
             $func = $matches[1];
             $args = $matches[2];
             if (function_exists($func)) {
                 $reflection = new ReflectionFunction($func);
                 if ($reflection->isInternal()) {
                     $_args = isset($_args[0]) ? array($_args[0]) : array();
                 }
             }
             return self::callFunc($_rule, $_args);
     }
     return false;
 }
コード例 #18
0
ファイル: amavis.stats.php プロジェクト: BillTheBest/1.6.x
function show_info($function, $basic = 0)
{
    $func = new ReflectionFunction($function);
    $ret = '';
    $ret .= "<pre><strong>Information:</strong>\n" . var_export($func->getDocComment(), 1) . "</pre>\n";
    if ($basic) {
        $ret .= "<pre><pre>===> The " . ($func->isInternal() ? 'internal' : 'user-defined') . " function '" . $func->getName() . "'\n" . "\tdeclared in " . $func->getFileName() . "\n\tlines " . $func->getStartLine() . " to " . $func->getEndline() . "</pre>\n";
    }
    return $ret;
}
コード例 #19
0
 /**
  * Shows a backtrace item
  *
  * @param int $n
  * @param array $trace
  */
 protected function _showTraceItem($n, $trace)
 {
     echo '<tr><td align="right" valign="top" class="error-number">#', $n, '</td><td>';
     if (isset($trace['class'])) {
         if (preg_match('/^Phalcon/', $trace['class'])) {
             echo '<span class="error-class"><a target="_new" href="http://docs.phalconphp.com/en/latest/api/', str_replace('\\', '_', $trace['class']), '.html">', $trace['class'], '</a></span>';
         } else {
             $classReflection = new \ReflectionClass($trace['class']);
             if ($classReflection->isInternal()) {
                 echo '<span class="error-class"><a target="_new" href="http://php.net/manual/en/class.', str_replace('_', '-', strtolower($trace['class'])), '.php">', $trace['class'], '</a></span>';
             } else {
                 echo '<span class="error-class">', $trace['class'], '</span>';
             }
         }
         echo $trace['type'];
     }
     if (isset($trace['class'])) {
         echo '<span class="error-function">', $trace['function'], '</span>';
     } else {
         if (function_exists($trace['function'])) {
             $functionReflection = new \ReflectionFunction($trace['function']);
             if ($functionReflection->isInternal()) {
                 echo '<span class="error-function"><a target="_new" href="http://php.net/manual/en/function.', str_replace('_', '-', $trace['function']), '.php">', $trace['function'], '</a></span>';
             } else {
                 echo '<span class="error-function">', $trace['function'], '</span>';
             }
         } else {
             echo '<span class="error-function">', $trace['function'], '</span>';
         }
     }
     if (isset($trace['args'])) {
         $arguments = array();
         foreach ($trace['args'] as $argument) {
             if (is_scalar($argument)) {
                 if (is_bool($argument)) {
                     if ($argument) {
                         $arguments[] = '<span class="error-parameter">true</span>';
                     } else {
                         $arguments[] = '<span class="error-parameter">null</span>';
                     }
                     continue;
                 }
                 if (is_string($argument)) {
                     $argument = $this->_escapeString($argument);
                 }
                 $arguments[] = '<span class="error-parameter">' . $argument . '</span>';
             } else {
                 if (is_object($argument)) {
                     if (method_exists($argument, 'dump')) {
                         $arguments[] = '<span class="error-parameter">Object(' . get_class($argument) . ': ' . $this->_getArrayDump($argument->dump()) . ')</span>';
                     } else {
                         $arguments[] = '<span class="error-parameter">Object(' . get_class($argument) . ')</span>';
                     }
                 } else {
                     if (is_array($argument)) {
                         $arguments[] = '<span class="error-parameter">Array(' . $this->_getArrayDump($argument) . ')</span>';
                     } else {
                         if (is_null($argument)) {
                             $arguments[] = '<span class="error-parameter">null</span>';
                             continue;
                         }
                     }
                 }
             }
         }
         echo '(' . join(', ', $arguments) . ')';
     }
     if (isset($trace['file'])) {
         echo '<br/><span class="error-file">', $trace['file'], ' (', $trace['line'], ')</span>';
     }
     echo '</td></tr>';
     if ($this->_showFiles) {
         if (isset($trace['file'])) {
             echo '</table>';
             $line = $trace['line'];
             $lines = file($trace['file']);
             if ($this->_showFileFragment) {
                 $numberLines = count($lines);
                 $firstLine = $line - 7 < 1 ? 1 : $line - 7;
                 $lastLine = $line + 5 > $numberLines ? $numberLines : $line + 5;
                 echo "<pre class='prettyprint highlight:" . $firstLine . ":" . $line . " linenums:" . $firstLine . "'>";
             } else {
                 $firstLine = 1;
                 $lastLine = count($lines) - 1;
                 echo "<pre class='prettyprint highlight:" . $firstLine . ":" . $line . " linenums error-scroll'>";
             }
             for ($i = $firstLine; $i <= $lastLine; ++$i) {
                 if ($this->_showFileFragment) {
                     if ($i == $firstLine) {
                         if (preg_match('#\\*\\/$#', rtrim($lines[$i - 1]))) {
                             $lines[$i - 1] = str_replace("* /", "  ", $lines[$i - 1]);
                         }
                     }
                 }
                 if ($lines[$i - 1] != PHP_EOL) {
                     $lines[$i - 1] = str_replace("\t", "  ", $lines[$i - 1]);
                     echo htmlentities($lines[$i - 1], ENT_COMPAT, 'UTF-8');
                 } else {
                     echo '&nbsp;' . "\n";
                 }
             }
             echo '</pre>';
             echo '<table cellspacing="0">';
         }
     }
 }
コード例 #20
0
ファイル: Debug.php プロジェクト: sssAlchemy/Panda
 /**
  * Show reflection
  *
  * Show reflection
  *
  * <code>
  * Panda_Debug::reflect('BEAR_Form');  // Class
  * Panda_Debug::reflect($obj);        // Objecy
  * Panda_Debug::reflect('p');         // Function
  * </code>
  *
  * @param string $target      target
  * @param boll   $cehckParent check parent class
  *
  * @return void
  */
 public static function reflect($target, $cehckParent = false)
 {
     if (is_object($target)) {
         $target = get_class($target);
     }
     switch (true) {
         case function_exists($target):
             $ref = new ReflectionFunction($target);
             $info['name'] = $ref->isInternal() ? 'The internal ' : 'The user-defined ';
             $info['name'] .= $targetName = $ref->getName();
             $info['declare in'] = $ref->getFileName() . ' lines ' . $ref->getStartLine() . ' to ' . $ref->getEndline();
             $info['Documentation'] = $ref->getDocComment();
             $statics = $ref->getStaticVariables();
             if ($statics) {
                 $info['Static variables'] = $statics;
             }
             $type = 'function';
             break;
         case class_exists($target, false):
             $ref = new ReflectionClass($target);
             $type = 'class';
             $info['name'] = $ref->isInternal() ? 'The internal ' : 'The user-defined ';
             $info['name'] .= $ref->isAbstract() ? ' abstract ' : '';
             $info['name'] .= $ref->isFinal() ? ' final ' : '';
             $info['name'] .= $ref->isInterface() ? 'interface ' : 'class ';
             $info['name'] .= $targetName = $ref->getName();
             $info['declare in'] = $ref->getFileName() . ' lines ' . $ref->getStartLine() . ' to ' . $ref->getEndline();
             $info['modifiers'] = Reflection::getModifierNames($ref->getModifiers());
             $info['Documentation'] = $ref->getDocComment();
             $info['Implements'] = $ref->getInterfaces();
             $info['Constants'] = $ref->getConstants();
             foreach ($ref->getProperties() as $prop) {
                 // ReflectionProperty クラスのインスタンスを生成する
                 $propRef = new ReflectionProperty($targetName, $prop->name);
                 if ($propRef->isPublic()) {
                     $porps[] = $prop->name;
                 }
             }
             //            $info['Public Properties'] = $porps;
             foreach ($ref->getMethods() as $method) {
                 $methodRef = new ReflectionMethod($targetName, $method->name);
                 if ($methodRef->isPublic() || $method->isStatic()) {
                     $final = $method->isFinal() ? 'final ' : '';
                     $pubic = $method->isPublic() ? 'public ' : '';
                     $static = $method->isStatic() ? ' static ' : '';
                     $methods[] = sprintf("%s%s%s %s", $final, $pubic, $static, $method->name);
                 }
             }
             $info['Public Methods'] = $methods;
             if ($ref->isInstantiable() && is_object($target)) {
                 $info['isInstance ?'] = $ref->isInstance($target) ? 'yes' : 'no';
             }
             if ($parent) {
                 $info['parent'] .= $ref->getParentClass();
             }
             break;
         default:
             $type = 'Invalid Object/Class';
             $targetName = $target;
             $info = null;
             break;
     }
     print_a($info, "show_objects:1;label: Reflection of {$type} '{$targetName}'");
 }
コード例 #21
0
ファイル: Errorhandler.php プロジェクト: ksst/kf
 /**
  * getDebugBacktrace.
  *
  * Transforms the output of php's debug_backtrace() and exception backtraces
  * to a more readable html format.
  *
  * @return string $backtrace_string contains the backtrace
  */
 public static function getDebugBacktrace($trace = null)
 {
     // show backtraces only in DEBUG mode
     if (defined('DEBUG') === false xor DEBUG === 0) {
         return;
     }
     // Normally backtraces are incomming from exceptions.
     // But, when called from the errorhandler, we need to fetch the traces ourselfs.
     if ($trace === null) {
         if (function_exists('xdebug_get_function_stack')) {
             $trace = xdebug_get_function_stack();
         } else {
             $trace = debug_backtrace();
         }
         /*
          * Now we get rid of several last calls in the backtrace stack,
          * to get nearer to the relevant error position in the stack.
          *
          * What exactly happens is: we shift-off the last 3 calls to
          * 1) getDebugBacktrace()   [this method itself]
          * 2) yellowScreenOfDeath() [our exception and error display method]
          * 3) trigger_error()       [php core function call]
          */
         $trace = array_slice($trace, 3);
     }
     /*
      * Assemble the html for the backtrace panel
      */
     $html = '';
     $html .= '<div id="panel3" class="panel"><h3>Backtrace</h3>';
     $html .= '<table class="cs-backtrace-table" width="95%">';
     // table row 1 - header
     $html .= '<tr><th width="2%">Callstack</th><th>Function</th><th width="46%">Location</th></tr>';
     // the number of backtraces
     $backtraces_counter_i = count($trace) - 1;
     for ($i = 0; $i <= $backtraces_counter_i; ++$i) {
         $html .= '<tr>';
         // Position in the Callstack
         $html .= '<td align="center">' . ($backtraces_counter_i - $i + 1) . '</td>';
         if (isset($trace[$i]['class']) === false) {
             $html .= '<td>[A PHP Core Function Call]</td>';
         } else {
             // replace trace type string with it's operator
             if ($trace[$i]['type'] === 'dynamic') {
                 $trace[$i]['type'] = '->';
             } else {
                 $trace[$i]['type'] = '::';
             }
             $html .= '<td>';
             // show the function call, e.g. Class->Method() or Class::Method()
             $html .= $trace[$i]['class'] . $trace[$i]['type'] . $trace[$i]['function'] . '()';
             // if the class is one of our own, add backlink to API Documentation
             if (1 === preg_match('/^Koch/', $trace[$i]['class'])) {
                 $html .= '<span class="error-class">';
                 $html .= '<a target="_new" href="http://docs.kf.com/en/latest/api/';
                 $html .= str_replace('\\', '_', $trace[$i]['class']);
                 $html .= '.html"> ' . $trace[$i]['class'] . '</a></span>';
             } else {
                 // else it's a php internal class, then add a backlink to the php manual
                 $classReflection = new \ReflectionClass($trace[$i]['class']);
                 if ($classReflection->isInternal()) {
                     $html .= '<span class="error-class"><a target="_new" href="http://php.net/manual/en/class.';
                     $html .= str_replace('_', '-', strtolower($trace[$i]['class']));
                     $html .= '.php">' . $trace[$i]['class'] . '</a></span>';
                 } else {
                     $html .= '<span class="error-class">' . $trace[$i]['class'] . '</span>';
                 }
             }
             // is this a normal php function? if yes, add a backlink to the php manual
             if (function_exists($trace[$i]['function'])) {
                 $functionReflection = new \ReflectionFunction($trace[$i]['function']);
                 if ($functionReflection->isInternal()) {
                     $html .= '<span class="error-function">';
                     $html .= '<a target="_new" href="http://php.net/manual/en/function.';
                     $html .= str_replace('_', '-', $trace[$i]['function']);
                     $html .= '.php">' . $trace[$i]['function'] . '</a></span>';
                 }
             }
             // XDebug uses the array key 'params' for the method parameters array
             // PHP backtrace uses 'args', so let's rename to 'args'
             if (isset($trace[$i]['params'])) {
                 $trace[$i]['args'] = $trace[$i]['params'];
                 unset($trace[$i]['params']);
             }
             // Method Arguments
             if (isset($trace[$i]['args']) && empty($trace[$i]['args']) === false) {
                 // the number of arguments (method parameters)
                 $backtrace_counter_j = count($trace[$i]['args']) - 1;
                 // use reflection to get the method parameters (and their names for display)
                 $reflected_method = new \ReflectionMethod($trace[$i]['class'], $trace[$i]['function']);
                 /* @var $reflected_params \ReflectionParameter */
                 $reflected_params = $reflected_method->getParameters();
                 // render a table with method parameters
                 // argument position | name | type | value
                 $html .= '<table style="border-collapse: collapse;">';
                 $html .= '<tr><th style="line-height: 0.8em;" colspan="4">Parameters</th></tr>';
                 $html .= '<tr style="line-height: 0.8em;">';
                 $html .= '<th>Pos</th><th>Name = Default Value</th><th>Type</th><th>Value</th></tr>';
                 // loop over all arguments
                 for ($j = 0; $j <= $backtrace_counter_j; ++$j) {
                     // fetch data for this argument
                     $data = self::formatBacktraceArgument($trace[$i]['args'][$j]);
                     // fetch current reflection parameter object
                     $parameter = $reflected_params[$j];
                     // get just the parameter name and it's default value
                     preg_match('/\\[ ([^[]+) \\]/', $parameter, $matches);
                     $html .= '<tr>';
                     $html .= '<td>' . ($j + 1) . '</td>';
                     // pos
                     $html .= '<td>' . $matches['1'] . '</td>';
                     // name
                     $html .= '<td>' . $data['type'] . '</td>';
                     // type
                     $html .= '<td>' . $data['arg'] . '</td>';
                     // value $defaultValue
                 }
                 $html .= '</tr></table>';
             }
             $html .= '</td>';
         }
         // Location with Link
         if (isset($trace[$i]['file'])) {
             $html .= '<td>' . self::getFileLink($trace[$i]['file'], $trace[$i]['line']) . '</td>';
         }
         $html .= '</tr>';
     }
     $html .= '</table></div>';
     return $html;
 }
コード例 #22
0
ファイル: reflection.php プロジェクト: alphaxxl/hhvm
var_dump($rf->getName());
print "\n";
print "--- getNumberOfParameters(\"f\") ---\n";
var_dump($rf->getNumberOfParameters());
print "\n";
print "--- getNumberOfRequiredParameters(\"f\") ---\n";
var_dump($rf->getNumberOfRequiredParameters());
print "\n";
print "--- getParameters(\"f\") ---\n";
var_dump($rf->getParameters());
print "\n";
print "--- getStaticVariables(\"f\") ---\n";
var_dump($rf->getStaticVariables());
print "\n";
print "--- isInternal(\"f\") ---\n";
var_dump($rf->isInternal());
print "\n";
print "--- isUserDefined(\"f\") ---\n";
var_dump($rf->isUserDefined());
print "\n";
print "--- returnsReference(\"f\") ---\n";
var_dump($rf->returnsReference());
print "\n";
print "--- export(\"f\") ---\n";
var_dump($rf->export('f', true));
print "\n";
# invoke() can't be used because $b is pass-by-reference.
print "--- invokeArgs(\"f\") ---\n";
$b = "b";
var_dump($rf->invokeArgs(array("a", &$b, "c")));
var_dump($rf->invokeArgs(array("a", &$b, "c")));
コード例 #23
0
ファイル: PHP_Highlight.php プロジェクト: emma5021/toba
 /**
  * Parse the loaded string into an array
  * Source is returned with the element key corresponding to the line number
  *
  * @access  public
  * @param   bool        $funcref        Reference functions to the PHP manual
  * @return  array       An array of highlighted source code
  */
 function toArray($funcref = true)
 {
     // Ensure source has been loaded
     if ($this->_source == false) {
         return false;
     }
     // Init
     $tokens = token_get_all($this->_source);
     $manual = $this->manual;
     $span = $this->span;
     $i = 0;
     $out = array();
     $out[$i] = '';
     // Loop through each token
     foreach ($tokens as $j => $token) {
         // Single char
         if (is_string($token)) {
             // Skip token2color check for speed
             $out[$i] .= sprintf($span, $this->highlight['keyword'], htmlspecialchars($token));
             // Heredocs behave strangely
             list($tb) = isset($tokens[$j - 1]) ? $tokens[$j - 1] : false;
             if ($tb == T_END_HEREDOC) {
                 $out[++$i] = '';
             }
             continue;
         }
         // Proper token
         list($token, $value) = $token;
         // Make the value safe
         $value = htmlspecialchars($value);
         $value = str_replace($this->replace[0], $this->replace[1], $value);
         // Process
         if ($value === "\n") {
             // End this line and start the next
             $out[++$i] = '';
         } else {
             // Function linking
             if ($funcref === true && $token === T_STRING) {
                 // Look ahead 1, look ahead 2, and look behind 3
                 if ((isset($tokens[$j + 1]) && $tokens[$j + 1] === '(' || isset($tokens[$j + 2]) && $tokens[$j + 2] === '(') && isset($tokens[$j - 3][0]) && $tokens[$j - 3][0] !== T_FUNCTION && function_exists($value)) {
                     $funcion = new ReflectionFunction($value);
                     // Insert the manual link
                     if ($funcion->isInternal()) {
                         $value = sprintf($manual, $value, $value);
                     }
                 }
             }
             // Explode token block
             $lines = explode("\n", $value);
             foreach ($lines as $jj => $line) {
                 $line = trim($line);
                 if ($line !== '') {
                     $out[$i] .= sprintf($span, $this->_token2color($token), $line);
                 }
                 // Start a new line
                 if (isset($lines[$jj + 1])) {
                     $out[++$i] = '';
                 }
             }
         }
     }
     return $out;
 }
コード例 #24
0
ファイル: Wrapper.php プロジェクト: TsobuEnterprise/phpxmlrpc
 /**
  * Introspect a php callable and its phpdoc block and extract information about its signature
  *
  * @param callable $callable
  * @param string $plainFuncName
  * @return array|false
  */
 protected function introspectFunction($callable, $plainFuncName)
 {
     // start to introspect PHP code
     if (is_array($callable)) {
         $func = new \ReflectionMethod($callable[0], $callable[1]);
         if ($func->isPrivate()) {
             error_log('XML-RPC: ' . __METHOD__ . ': method to be wrapped is private: ' . $plainFuncName);
             return false;
         }
         if ($func->isProtected()) {
             error_log('XML-RPC: ' . __METHOD__ . ': method to be wrapped is protected: ' . $plainFuncName);
             return false;
         }
         if ($func->isConstructor()) {
             error_log('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the constructor: ' . $plainFuncName);
             return false;
         }
         if ($func->isDestructor()) {
             error_log('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the destructor: ' . $plainFuncName);
             return false;
         }
         if ($func->isAbstract()) {
             error_log('XML-RPC: ' . __METHOD__ . ': method to be wrapped is abstract: ' . $plainFuncName);
             return false;
         }
         /// @todo add more checks for static vs. nonstatic?
     } else {
         $func = new \ReflectionFunction($callable);
     }
     if ($func->isInternal()) {
         // Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
         // instead of getparameters to fully reflect internal php functions ?
         error_log('XML-RPC: ' . __METHOD__ . ': function to be wrapped is internal: ' . $plainFuncName);
         return false;
     }
     // retrieve parameter names, types and description from javadoc comments
     // function description
     $desc = '';
     // type of return val: by default 'any'
     $returns = Value::$xmlrpcValue;
     // desc of return val
     $returnsDocs = '';
     // type + name of function parameters
     $paramDocs = array();
     $docs = $func->getDocComment();
     if ($docs != '') {
         $docs = explode("\n", $docs);
         $i = 0;
         foreach ($docs as $doc) {
             $doc = trim($doc, " \r\t/*");
             if (strlen($doc) && strpos($doc, '@') !== 0 && !$i) {
                 if ($desc) {
                     $desc .= "\n";
                 }
                 $desc .= $doc;
             } elseif (strpos($doc, '@param') === 0) {
                 // syntax: @param type $name [desc]
                 if (preg_match('/@param\\s+(\\S+)\\s+(\\$\\S+)\\s*(.+)?/', $doc, $matches)) {
                     $name = strtolower(trim($matches[2]));
                     //$paramDocs[$name]['name'] = trim($matches[2]);
                     $paramDocs[$name]['doc'] = isset($matches[3]) ? $matches[3] : '';
                     $paramDocs[$name]['type'] = $matches[1];
                 }
                 $i++;
             } elseif (strpos($doc, '@return') === 0) {
                 // syntax: @return type [desc]
                 if (preg_match('/@return\\s+(\\S+)(\\s+.+)?/', $doc, $matches)) {
                     $returns = $matches[1];
                     if (isset($matches[2])) {
                         $returnsDocs = trim($matches[2]);
                     }
                 }
             }
         }
     }
     // execute introspection of actual function prototype
     $params = array();
     $i = 0;
     foreach ($func->getParameters() as $paramObj) {
         $params[$i] = array();
         $params[$i]['name'] = '$' . $paramObj->getName();
         $params[$i]['isoptional'] = $paramObj->isOptional();
         $i++;
     }
     return array('desc' => $desc, 'docs' => $docs, 'params' => $params, 'paramDocs' => $paramDocs, 'returns' => $returns, 'returnsDocs' => $returnsDocs);
 }
コード例 #25
0
ファイル: Debug.php プロジェクト: kumfo/Scene-php
 /**
  * Shows a backtrace item
  *
  * @param int $n
  * @param array $trace
  * @return string
  * @throws Exception
  */
 protected function showTraceItem($n, $trace)
 {
     /**
      * Every trace in the backtrace have a unique number
      */
     $html = '<tr><td align="right" valign="top" class="error-number">#' . $n . '</td><td>';
     if (isset($trace["class"])) {
         $className = $trace["class"];
         /**
          * We assume that classes starting by Phalcon are framework's classes
          */
         if (preg_match("/^Scene/", $className)) {
             /**
              * Prepare the class name according to the Phalcon's conventions
              */
             $prepareUriClass = str_replace("\\", "/", $className);
             /**
              * Generate a link to the official docs
              */
             $html .= '<span class="error-class"><a target="_new" href="//api.scene.ainstant.com/class/' . $prepareUriClass . '.html">' . $className . '</a></span>';
         } else {
             $classReflection = new \ReflectionClass($className);
             /**
              * Check if classes are PHP's classes
              */
             if ($classReflection->isInternal()) {
                 $prepareInternalClass = str_replace("_", "-", strtolower($className));
                 /**
                  * Generate a link to the official docs
                  */
                 $html .= '<span class="error-class"><a target="_new" href="http://php.net/manual/en/class.' . $prepareInternalClass . '.php">' . $className . '</a></span>';
             } else {
                 $html .= '<span class="error-class">' . $className . '</span>';
             }
         }
         /**
          * Object access operator: static/instance
          */
         $html .= $trace['type'];
     }
     /**
      * Normally the backtrace contains only classes
      */
     $functionName = $trace['function'];
     if (isset($trace['class'])) {
         $html .= '<span class="error-function">' . $functionName . '</span>';
     } else {
         /**
          * Check if the function exists
          */
         if (function_exists($functionName)) {
             $functionReflection = new \ReflectionFunction($functionName);
             /**
              * Internal functions links to the PHP documentation
              */
             if ($functionReflection->isInternal()) {
                 /**
                  * Prepare function's name according to the conventions in the docs
                  */
                 $preparedFunctionName = str_replace("_", "-", $functionName);
                 $html .= '<span class="error-function"><a target="_new" href="http://php.net/manual/en/function.' . $preparedFunctionName . '.php">' . $functionName . '</a></span>';
             } else {
                 $html .= '<span class="error-function">' . $functionName . '</span>';
             }
         } else {
             $html .= '<span class="error-function">' . $functionName . '</span>';
         }
     }
     /**
      * Check for arguments in the function
      */
     if (isset($trace['args'])) {
         $traceArgs = $trace['args'];
         if (count($traceArgs)) {
             $arguments = [];
             foreach ($traceArgs as $argument) {
                 /**
                  * Every argument is generated using _getVarDump
                  * Append the HTML generated to the argument's list
                  */
                 $arguments[] = '<span class="error-parameter">' . $this->_getVarDump($argument) . '</span>';
             }
             /**
              * Join all the arguments
              */
             $html .= '(' . join(', ', $arguments) . ')';
         } else {
             $html .= '()';
         }
     }
     /**
      * When "file" is present, it usually means the function is provided by the user
      */
     if (isset($trace['file'])) {
         $filez = $trace['file'];
         $line = (string) $trace['line'];
         /**
          * Realpath to the file and its line using a special header
          */
         $html .= '<br/><div class="error-file">' . $filez . ' (' . $line . ')</div>';
         $showFiles = $this->_showFiles;
         if ($showFiles) {
             /**
              * Open the file to an array using "file", this respects the openbase-dir directive
              */
             $lines = file($filez);
             $numberLines = count($lines);
             $showFileFragment = $this->_showFileFragment;
             /**
              * File fragments just show a piece of the file where the exception is located
              */
             if ($showFileFragment) {
                 /**
                  * Take seven lines back to the current exception's line, @TODO add an option for this
                  */
                 $beforeLine = $line - 7;
                 /**
                  * Check for overflows
                  */
                 if ($beforeLine < 1) {
                     $firstLine = 1;
                 } else {
                     $firstLine = $beforeLine;
                 }
                 /**
                  * Take five lines after the current exception's line, @TODO add an option for this
                  */
                 $afterLine = $line + 5;
                 /**
                  * Check for overflows
                  */
                 if ($afterLine > $numberLines) {
                     $lastLine = $numberLines;
                 } else {
                     $lastLine = $afterLine;
                 }
                 $html .= '<pre class="prettyprint highlight:' . $firstLine . ':' . $line . " linenums:" . $firstLine . '">';
             } else {
                 $firstLine = 1;
                 $lastLine = $numberLines;
                 $html .= '<pre class="prettyprint highlight:' . $firstLine . ':' . $line . ' linenums error-scroll">';
             }
             $i = $firstLine;
             while ($i <= $lastLine) {
                 /**
                  * Current line in the file
                  */
                 $linePosition = $i - 1;
                 /**
                  * Current line content in the piece of file
                  */
                 $currentLine = $lines[$linePosition];
                 /**
                  * File fragments are cleaned, removing tabs and comments
                  */
                 if ($showFileFragment) {
                     if ($i == $firstLine) {
                         if (preg_match("#\\*\\/#", rtrim($currentLine))) {
                             $currentLine = str_replace("* /", " ", $currentLine);
                         }
                     }
                 }
                 /**
                  * Print a non break space if the current line is a line break, this allows to show the html zebra properly
                  */
                 if ($currentLine == "\n" || $currentLine == "\r\n") {
                     $html .= "&nbsp;\n";
                 } else {
                     /**
                      * Don't escape quotes
                      * We assume the file is utf-8 encoded, @TODO add an option for this
                      */
                     $html .= htmlentities(str_replace("\t", "  ", $currentLine), ENT_COMPAT, "UTF-8");
                 }
                 $i++;
             }
             $html .= '</pre>';
         }
     }
     $html .= '</td></tr>';
     return $html;
 }