Library emulating the PHP internal reflection using just the tokenized source code

Overview

PHP Token Reflection

Build Status

In short, this library emulates the PHP reflection model using the tokenized PHP source.

The basic concept is, that any reflection is possible to process the particular part of the token array describing the reflected element. It is also able to find out if there are any child elements (a class reflection is able to find method definitions in the source, for example), create their reflections and pass the appropriate part of the token array to them.

This concept allows us to keep the parser code relatively simple and easily maintainable. And we are able to to create all reflections in a single pass. That is absolutely crucial for the performance of the library.

All reflection instances are being kept in a TokenReflection\Broker instance and all reflections know the broker that created them. This is very important, because a class reflection, for example, holds all its constants, methods and properties reflections instantiated inside, however it knows absolutely nothing about its parent class or the interfaces it implements. It knows just their fully qualified names. So when you call $reflectionClass->getParentClass();, the class reflection asks the Broker for a reflection of a class by its name and returns it.

An interesting thing happens when there is a parent class defined but it was not processed (in other words, you ask the Broker for a class that it does not know). It still returns a reflection! Yes, we do have reflections for classes that do not exist! COOL!

There are reflections for file (*), file-namespace (*), namespace, class, function/method, constant, property and parameter. You will not normally get in touch with those marked with an asterisk but they are used internally.

ReflectionFile is the topmost structure in our reflection tree. It gets the whole tokenized source and tries to find namespaces there. If it does, it creates ReflectionFileNamespace instances and passes them the appropriate part of the tokens array. If not, it creates a single pseudo-namespace (called no-namespace) a passes the whole tokenized source to it.

ReflectionFileNamespace gets the namespace definition from the file, finds out its name, other aliased namespaces and tries to find any defined constants, functions and classes. If it finds any, it creates their reflections and passes them the appropriate parts of the tokens array.

ReflectionNamespace is a similar (in name) yet quite different (in meaning) structure. It is a unique structure for every namespace and it holds all constants, functions and classes from this particular namespace inside. In fact, it is a simple container. It also is not created directly by any parent reflection, but the Broker creates it.

Why do we need two separate classes? Because namespaces can be split into many files and in each file it can have individual namespace aliases. And those have to be taken into consideration when resolving parent class/interface names. It means that a ReflectionFileNamespace is created for every namespace in every file and it parses its contents, resolves fully qualified names of all classes, their parents and interfaces. Later, the Broker takes all ReflectionFileNamespace instances of the same namespace and merges them into a single ReflectionNameaspace instance.

ReflectionClass, ReflectionFunction, ReflectionMethod, ReflectionParameter and ReflectionProperty work the same way like their internal reflection namesakes.

ReflectionConstants is our addition to the reflection model. There is not much it can do - it can return its name, value (we will speak about values later) and how it was defined.

(Almost) all reflection classes share a common base class, that defines some common functionality and interface. This means that our reflection model is much more unified than the internal one.

There are reflections for the tokenized source (those mentioned above), but also descendants of the internal reflection that implement our additional features (they both use the same interface). They represent the PHP's internal classes, functions, ... So when you ask the Broker for an internal class, it returns a TokenReflection\Php\ReflectionClass instance that encapsulates the internal reflection functionality and adds our features. And there is also the TokenReflection\Php\ReflectionConstant class that has no parent in the internal reflection model.

Remarks

From the beginning we tried to be as compatible as possible with the internal reflection (including things like returning the interface list in the same - pretty weird - order). However there are situations where it is just impossible (for example we prefer consistency over compatibility with the internal reflection and will not introduce this bug into the library :).

We are limited in the way we can handle constant values and property and parameter default values. When defined as a constant, we do our best to resolve its value (within parsed and internal constants) and use it. This is eventually made via a combination of var_export() and eval(). Yes, that sucks, but there is no better way. Moreover the referenced constant may not exist. In that case it is replaced by a ~~NOT RESOLVED~~ string.

Runtime constants are not supported.

When the library encounters a duplicate class, function or constant name, it converts the previously created reflection into an "invalid reflection" instance. That means that the parser is unable to distinguish between such classes and it is unable to build a proper class tree for example. And it throws an exception. When you catch this exception and continue to work with the Broker instance, the duplicate classes, functions or constants will have only one reflection and it will be an instance of Invalid\ReflectionClass, Invalid\ReflectionFunction or Invalid\ReflectionConstant respectively.

Usage

To be able to work with reflections you have to let the library parse the source code first. That is what TokenReflection\Broker does. It walks through the given directories, tokenizes PHP sources and caches reflection objects. Moreover, you cannot just instantiate a reflection class. You have to ask the Broker for the reflection. And once you have a reflection instance, everything works as expected :)

<?php
namespace TokenReflection;

$broker = new Broker(new Broker\Backend\Memory());
$broker->processDirectory('~/lib/Zend_Framework');

$class = $broker->getClass('Zend_Version'); // returns a TokenReflection\ReflectionClass instance
$class = $broker->getClass('Exception');    // returns a TokenReflection\Php\ReflectionClass instance
$class = $broker->getClass('Nonexistent');  // returns a TokenReflection\Dummy\ReflectionClass instance

$function = $broker->getFunction(...);
$constant = $broker->getConstant(...);

Requirements

The library requires PHP 5.3 with the tokenizer extension enabled. If you want to process PHAR archives, you will require the appropriate extension enabled as well.

Current status

The current version should support the vast majority of PHP internal reflection features and add many more.

Every release is tested using our testing package (several PHP frameworks and other libraries) and its compatibility is tested on all PHP versions of the 5.3 and 5.4 branch and the actual trunk.

Comments
  • Unexpected token found.

    Unexpected token found.

    The cause of the exception "Unexpected token found." was the T_GOTO token (line 127) in following part of the source code:

    114: 115: $this->goto = TEMPLATES . '/404.html'; 116: //throw new FwException('Unrecognized request [' . User::get_real_ip() . ']: ' . 117: // ov($_SERVER['REDIRECT_URL']), E_USER_NOTICE); 118: } 119: } 120: } 121:
    122: /** 123: * Include appropriate document 124: * 125: * @return void 126: */ *127: public function goto() 128: { 129: try { 130: HttpStatus::header(200); 131: if(!is_link($this->goto)) { 132: require_once

    The exception backtrace is following: #0 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionMethod.php(695): TokenReflection\ReflectionFunctionBase->parseReturnsReference(Object(TokenReflection\Stream\StringStream)) #1 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(121): TokenReflection\ReflectionMethod->parse(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionClass)) #2 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionBase.php(73): TokenReflection\ReflectionElement->parseStream(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionClass)) #3 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(104): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionClass)) #4 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionClass.php(1839): TokenReflection\ReflectionElement->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionClass)) #5 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(122): TokenReflection\ReflectionClass->parseChildren(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionFileNamespace)) #6 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionBase.php(73): TokenReflection\ReflectionElement->parseStream(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionFileNamespace)) #7 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(104): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFileNamespace)) #8 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionFileNamespace.php(299): TokenReflection\ReflectionElement->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFileNamespace)) #9 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(122): TokenReflection\ReflectionFileNamespace->parseChildren(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionFile)) #10 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionBase.php(73): TokenReflection\ReflectionElement->parseStream(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\ReflectionFile)) #11 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionElement.php(104): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFile)) #12 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionFile.php(121): TokenReflection\ReflectionElement->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFile)) #13 C:\Users\brano\tools\php\PEAR\TokenReflection\ReflectionBase.php(73): TokenReflection\ReflectionFile->parseStream(Object(TokenReflection\Stream\StringStream), NULL) #14 C:\Users\brano\tools\php\PEAR\TokenReflection\Broker.php(168): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream\StringStream), Object(TokenReflection\Broker)) #15 C:\Users\brano\tools\php\PEAR\ApiGen\Generator.php(235): TokenReflection\Broker->processString('<?php?/**? * Ge...', 'C:\Users\brano...') #16 C:\Users\brano\tools\php\apigen(130): ApiGen\Generator->parse() #17 {main}

    opened by thunderdox 3
  • Allow to set file extensions list for processDirectory()

    Allow to set file extensions list for processDirectory()

    Hi, first of all, big thanks for you hard work!

    I have small suggestion / improvement: It would be very nice to give the ability to customize which file types should be processed by processDirectory() method. I'm tried to parse my /usr/share/php/Zend directory and got this error:

    Stack trace:
    #0 /Users/josser/Projects/PHP-Token-Reflection/TokenReflection/Broker/Backend/Memory.php(423): TokenReflection\ReflectionNamespace->addFileNamespace(Object(TokenReflection\ReflectionFileNamespace))
    #1 /Users/josser/Projects/PHP-Token-Reflection/TokenReflection/Broker.php(207): TokenReflection\Broker\Backend\Memory->addFile(Object(TokenReflection\ReflectionFile))
    #2 /Users/josser/Projects/PHP-Token-Reflection/TokenReflection/Broker.php(275): TokenReflection\Broker->processFile('/usr/share/php/...', false)
    #3 /Users/josser/Projects/PHP-Token-Reflection/application/test.php(11): TokenReflection\Broker->processDirectory('/usr/share/php/...')
    #4 /Users/josser/Projects/PHP-Token-Reflection/application/test.php(16 in /Users/josser/Projects/PHP-Token-Reflection/TokenReflection/Broker.php on line 281```
    
    As you can see tokenizer wants to parse svn files and this causes an error. 
    Maybe ".php" and ".phtml" can be hardcoded but allow to override. 
    Thanks! 
    
    opened by josser 3
  • Support late static binding object initialization (`new static`)

    Support late static binding object initialization (`new static`)

    Currently, using late static binding object initialization (new static) looks like a malformed static variable declaration to ReflectionFunctionBase::parseStaticVariables():

    Could not process file /var/www/workspace/.../component/Component.php.
    Could not parse file contents.
    Could not parse TokenReflection\ReflectionFileNamespace ...\component child elements.
    Could not parse TokenReflection\ReflectionClass ...\component\Component child elements.
    Could not parse TokenReflection\ReflectionMethod factory child elements.
    Could not parse function/method "factory" static variables.
    Invalid token found: "(".
    
    #0 /usr/share/php/TokenReflection/ReflectionFunctionBase.php(285): TokenReflection\ReflectionFunctionBase->parseStaticVariables(Object(TokenReflection\Stream))
    #1 /usr/share/php/TokenReflection/ReflectionBase.php(154): TokenReflection\ReflectionFunctionBase->parseChildren(Object(TokenReflection\Stream), Object(TokenReflection\ReflectionClass))
    #2 /usr/share/php/TokenReflection/ReflectionClass.php(1493): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionClass))
    #3 /usr/share/php/TokenReflection/ReflectionBase.php(154): TokenReflection\ReflectionClass->parseChildren(Object(TokenReflection\Stream), Object(TokenReflection\ReflectionFileNamespace))
    #4 /usr/share/php/TokenReflection/ReflectionFileNamespace.php(274): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFileNamespace))
    #5 /usr/share/php/TokenReflection/ReflectionBase.php(154): TokenReflection\ReflectionFileNamespace->parseChildren(Object(TokenReflection\Stream), Object(TokenReflection\ReflectionFile))
    #6 /usr/share/php/TokenReflection/ReflectionFile.php(232): TokenReflection\ReflectionBase->__construct(Object(TokenReflection\Stream), Object(TokenReflection\Broker), Object(TokenReflection\ReflectionFile))
    #7 /usr/share/php/TokenReflection/ReflectionFile.php(54): TokenReflection\ReflectionFile->parse()
    #8 /usr/share/php/TokenReflection/Broker.php(107): TokenReflection\ReflectionFile->__construct(Object(TokenReflection\Stream), Object(TokenReflection\Broker))
    #9 /usr/share/php/ApiGen/Generator.php(159): TokenReflection\Broker->processFile('/var/www/worksp...')
    #10 /usr/bin/apigen(66): ApiGen\Generator->parse()
    #11 {main}
    

    This patch fixes it by keeping track of the previous token type, and ignores T_STATIC that follows T_NEW.

    opened by shesek 3
  • Support scalar expressions for constants

    Support scalar expressions for constants

    This allows ReflectionConstant to parse scalar expressions when defining constants, such as:

    const FOO = 1 ** 2;
    const BAR = array(1 => 'one');
    const BAZ = 'foo' . 'bar';
    const QUX = \Acme\Com\Demo::class;
    

    Should fix #62 and #69.

    opened by kdambekalns 2
  • Implementing / Extending PHP's built-in interfaces causes an error

    Implementing / Extending PHP's built-in interfaces causes an error

    When implementing (e.g. class foo implements ArrayAccess) or extending (e.g. interface bar extends Iterator) PHP's built-in interfaces, an array_combine(): Both parameters should have at least 1 element warning is raised, which is thrown as an \Nette\FatalErrorException exception and stops execution.

    When \TokenReflection\Php\ReflectionClass::getInterfaces() gets called on the built-in interface, getInterfaceNames() returns an empty array, which eventually calls array_combine() with empty arrays as the arguments and causes the Both parameters should have at least 1 element warning.

    I'm not sure why, but this doesn't happen with custom interfaces. It seems like getInterfaces() isn't getting called at all. Maybe a better solution would be to handle built-in interfaces in the same way custom ones are handled, instead of this patch.

    opened by shesek 2
  • Tests fail on PHP 5.4.11

    Tests fail on PHP 5.4.11

    TokenReflection $ ant phpunit
    Buildfile: /Users/www/phpstan/vendor/TokenReflection/build.xml
    
    phpunit:
         [exec] PHPUnit 3.7.19 by Sebastian Bergmann.
         [exec]
         [exec] Configuration read from /Users/www/phpstan/vendor/TokenReflection/build/phpunit.xml
         [exec]
         [exec] .........................................SSSS..................  63 / 216 ( 29%)
         [exec] ..........................F...FF.F............
         [exec] PHP Fatal error:  Trait method privatef has not been applied, because there are collisions with other trait methods on TokenReflection_Test_ClassTraits2 in /Users/www/phpstan/vendor/TokenReflection/tests/data/class/traits.php on line 51
         [exec] PHP Stack trace:
         [exec] PHP   1. {main}() /usr/local/Cellar/php54/5.4.11/bin/phpunit:0
         [exec] PHP   2. PHPUnit_TextUI_Command::main() /usr/local/Cellar/php54/5.4.11/bin/phpunit:46
         [exec] PHP   3. PHPUnit_TextUI_Command->run() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/TextUI/Command.php:129
         [exec] PHP   4. PHPUnit_TextUI_TestRunner->doRun() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/TextUI/Command.php:176
         [exec] PHP   5. PHPUn
         [exec] Fatal error: Trait method privatef has not been applied, because there are collisions with other trait methods on TokenReflectiit_Framework_TestSuite->run() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/TextUI/TestRunner.php:349
         [exec] PHP   6. PHPUnit_Frameworon_Test_ClassTraits2 in /Users/www/phpstan/vendor/TokenReflection/tests/data/class/traits.php on line 51
         [exec]
         [exec] Call Stack:
         [exec]     0.0003k_TestSuite->run() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:705
         [exec] PHP   7. PHPUnit_Framework_TestSui     227400   1. {main}() /usr/local/Cellar/php54/5.4.11/bin/phpunit:0
         [exec]     0.0040     517792   2. PHPUnit_TextUI_Command::main()te->runTest() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:745
         [exec] PHP   8. PHPUnit_Framework_TestCase->ru /usr/local/Cellar/php54/5.4.11/bin/phpunit:46
         [exec]     0.0041     518024   3. PHPUnit_TextUI_Command->run() /usr/local/Cellar/php54/n() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:775
         [exec] PHP   9. PHPUnit_Framework_TestResult->run() /usr5.4.11/lib/php/PHPUnit/TextUI/Command.php:129
         [exec]     0.2428    6312992   4. PHPUnit_TextUI_TestRunner->doRun() /usr/local/Cellar/ph/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:776
         [exec] PHP  10. PHPUnit_Framework_TestCase->runBare() /usr/local/p54/5.4.11/lib/php/PHPUnit/TextUI/Command.php:176
         [exec]     0.2658    6819320   5. PHPUnit_Framework_TestSuite->run() /usr/local/CellaCellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestResult.php:648
         [exec] PHP  11. PHPUnit_Framework_TestCase->runTest() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/TextUI/TestRunner.php:349
         [exec]     3.7369   17719728   6. PHPUnit_Framework_TestSuite->run() /usr/locar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:831
         [exec] PHP  12. ReflectionMethod->invokeArgs() /usr/local/Cellar/php54/5.4.11l/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:705
         [exec]     5.7816   21766192   7. PHPUnit_Framework_TestSuite->runTes/lib/php/PHPUnit/Framework/TestCase.php:976
         [exec] PHP  13. TokenReflection\ReflectionClassTest->testToString() /usr/local/Cellar/php54t() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:745
         [exec]     5.7816   21766192   8. PHPUnit_Framework_Test/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:976
         [exec] PHP  14. TokenReflection\Test->getClassReflection() /Users/www/phpstan/vendor/TokenReflection/tests/TokenReflection/ReflectionClassTest.php:1306
         [exec] PHP  15. TokenReflection\Test->getClassInternalReflection() Case->run() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestSuite.php:775
         [exec]     5.7817   21766192   9. PHPUnit_Framew/Users/www/phpstan/vendor/TokenReflection/tests/TokenReflection/Test.php:53
         [exec] PHP  16. require_once() /Users/www/phpstan/vendor/Toork_TestResult->run() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:776
         [exec]     5.7819   21767176  10. PHPUnkenReflection/tests/TokenReflection/Test.php:126
         [exec] it_Framework_TestCase->runBare() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestResult.php:648
         [exec]     5.7832   21796360  11. PHPUnit_Framework_TestCase->runTest() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:831
         [exec]     5.7833   21797168  12. ReflectionMethod->invokeArgs() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:976
         [exec]     5.7833   21797200  13. TokenReflection\ReflectionClassTest->testToString() /usr/local/Cellar/php54/5.4.11/lib/php/PHPUnit/Framework/TestCase.php:976
         [exec]     6.5991   22029520  14. TokenReflection\Test->getClassReflection() /Users/www/phpstan/vendor/TokenReflection/tests/TokenReflection/ReflectionClassTest.php:1306
         [exec]     6.5992   22029664  15. TokenReflection\Test->getClassInternalReflection() /Users/www/phpstan/vendor/TokenReflection/tests/TokenReflection/Test.php:53
         [exec]     6.5996   22046720  16. require_once('/Users/www/phpstan/vendor/TokenReflection/tests/data/class/traits.php') /Users/www/phpstan/vendor/TokenReflection/tests/TokenReflection/Test.php:126
         [exec]
    
    BUILD FAILED
    /Users/www/phpstan/vendor/TokenReflection/build.xml:101: exec returned: 255
    
    Total time: 7 seconds
    

    Output of my php -v:

    PHP 5.4.11 (cli) (built: Mar  8 2013 20:44:06)
    Copyright (c) 1997-2013 The PHP Group
    Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
        with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans
    

    Am I doing something wrong or is there simply a bug in the code?

    opened by ondrejmirtes 1
  • TokenReflection\ReflectionMethod::getPrettyName returns incorrect values

    TokenReflection\ReflectionMethod::getPrettyName returns incorrect values

    TokenReflection\ReflectionMethod::getPrettyName returns values like "1::myMethodName" Problem is in folowing code: null !== $this->declaringClassName ?: $this->declaringTraitName Class name is converted to boolean here. You may check this behavior easy: php -r "var_dump(null !== 'one' ?: 'two' );"

    opened by Nayjest 1
  • Add support for parsing Doctrine annotations

    Add support for parsing Doctrine annotations

    Many projects use doctine annotations to store metadata for class, however ApiGen doesn't support such format, for example, in Symfony2 there is Route annotation @Route("/index", defaults={"_format" = "json"})

    Can you add a support for @Annotation annotation in class to use such classes for storing metadata ang show this information in generated documentation?

    opened by lisachenko 1
  • Invalid value definition

    Invalid value definition

    Apigen fails and blames TokenReflection library. It states the cause of the exception was:

    '"Invalid value definition." was the T_WHITESPACE token (line 28) in following part of SomeClass::ACCESS_DEPRECATED source code'.

    The reported line looks like ' const ACCESS_DEPRECATED = '3' ;' (tab indents, space after the constant value before the semicolon). Removing the space after the constant value helps as a workaround.

    See the stacktrace: https://gist.github.com/1865268

    opened by RadekDvorak 1
  • Fix problem with docBlock

    Fix problem with docBlock

    Hi.

    I added test and fix problem with docComments, when after docBlock many line breaks. Example:

    <?php
    
    /**
     * TokenReflection_Test_ClassDocCommentManyLines.
     *
     * @copyright Copyright (c) 2011
     * @author author
     * @see http://php.net
     */
    
    
    
    
    
    
    
    
    
    
    
    class TokenReflection_Test_ClassDocCommentManyLines
    {
    }
    
    opened by grevus 1
  • Alternative class property definition error, missing doc comment (1.0.1)

    Alternative class property definition error, missing doc comment (1.0.1)

    <?php
    class PropertyClass {
        public
            /** Holds current length */
            $length = 0,
    
            /** Remembers current index */
            $index;
    }
    
    $rc = new ReflectionClass("PropertyClass");
    foreach ($rc->getProperties() as $p) {
        var_dump(array(
            "name"      => $p->getName(),
            "doc"       => $p->getDocComment(),
            "modifiers" => Reflection::getModifierNames(
                $p->getModifiers())));
    }
    

    The output of this is:

    runfalk@dev:~$ php -v
    PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cli) (built: Jun 28 2011 13:13:26) 
    Copyright (c) 1997-2009 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
        with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
        with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH
    runfalk@dev:~$ php test.php 
    array(3) {
      ["name"]=>
      string(6) "length"
      ["doc"]=>
      string(27) "/** Holds current length */"
      ["modifiers"]=>
      array(1) {
        [0]=>
        string(6) "public"
      }
    }
    array(3) {
      ["name"]=>
      string(5) "index"
      ["doc"]=>
      string(30) "/** Remembers current index */"
      ["modifiers"]=>
      array(1) {
        [0]=>
        string(6) "public"
      }
    }
    

    If the file above is saved as test.php:

    <?php
    namespace TokenReflection;
    
    spl_autoload_register(function($class) {
        if (!file_exists(sprintf('TR/%s.php', str_replace('\\', DIRECTORY_SEPARATOR, $class)))) {
            var_dump($class, debug_backtrace());
            die();
        }
        require sprintf('TR/%s.php', str_replace('\\', DIRECTORY_SEPARATOR, $class));
    });
    
    $tr = new Broker(new Broker\Backend\Memory());
    $tr->processFile("test.php");
    
    foreach ($tr->getClass("PropertyClass")->getProperties() as $p) {
        var_dump(array(
            "name"      => $p->getName(),
            "doc"       => $p->getDocComment(),
            "modifiers" => \Reflection::getModifierNames(
                $p->getModifiers())));
    }
    

    This yeilds:

    array(3) {
      ["name"]=>
      string(6) "length"
      ["doc"]=>
      bool(false)
      ["modifiers"]=>
      array(1) {
        [0]=>
        string(6) "public"
      }
    }
    array(3) {
      ["name"]=>
      string(5) "index"
      ["doc"]=>
      string(30) "/** Remembers current index */"
      ["modifiers"]=>
      array(1) {
        [0]=>
        string(6) "public"
      }
    }
    

    Notice that the doc for length is not displaying at all.

    opened by runfalk 1
  • Change deprecated syntax for array access

    Change deprecated syntax for array access

    Two instances of the code use a deprecated (as of PHP 8) way of accessing arrays, by using curly braces ({}).

    This generates a PHP Fatal Error at runtime (tested on PHP 8.0.8):

    PHP Fatal error:  Array and string offset access syntax with curly braces is no longer supported in andrewsville/php-token-reflection/TokenReflection/Broker.php on line 284
    

    This PR changes those places to use square braces instead.

    opened by nilllzz 0
  • Fatal error in PHP nightly builds (7.2.0-dev)

    Fatal error in PHP nightly builds (7.2.0-dev)

    In PHP nightly builds (PHP 7.2.0-dev) used on Travis CI, I'm receiving the following fatal error:

    PHP Fatal error:  Declaration of ReflectionClass::newInstance(...$args) must be compatible with TokenReflection\IReflectionClass::newInstance($args) in /home/travis/build/ramsey/uuid/vendor/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionClass.php on line 27
    

    See here for details: https://travis-ci.org/ramsey/uuid/jobs/212472243

    opened by ramsey 0
  • [TokenReflection\Exception\ParseException] Unexpected token found.

    [TokenReflection\Exception\ParseException] Unexpected token found.

    Parser couldn't correctly parse keyword "class". For example:

    some\name\space\SomeClass:class // couldn't parse 'someOtherKey => 'some\name\space\SomeClass' // as string everything is correct. ];

    I faced with this issue, when use Yii2 array fixtures in codeception. I hope, it would be helpful fo smb.

    opened by alexrgb 1
  • Retrieving Reflection of Generic Lines

    Retrieving Reflection of Generic Lines

    Hello, thanks for the great tool.

    The basic concept is, that any reflection is possible to process the particular part of the token array describing the reflected element.

    I could pull doc-block descriptions of a class like this.

    $broker = new Broker(new Broker\Backend\Memory());
    $broker->processDirectory( dirname( __FILE__ ) . '/project_x' );
    $class = $broker->getClass( 'MyClassBase' );
    $long_description = $class->getAnnotation(ReflectionAnnotation::LONG_DESCRIPTION);
    

    I'm wondering if there is a way to retrieve doc-block contents of an arbitrary line of code. Say, there is a line which is neither a class, method, constant, nor function declaration and it is documented with the docblock format.

    /**
     * This is for arbitrary contents.
     * 
     * Trying to see if custom doc-blocks can be included.
     * 
     * @package     CustomLine
     */
    doAction( 'custom_line' );
    

    When I print out the contents of $broker by doing like print_r( $broker, true );, I see the doc-block of such an above case is parsed and stored in the object. What I want to do is to list doc-block contents of generic lines which belong to a certain package or namespace. Is there a method like $broker->getMisc() or something?

    opened by onet4 0
  • PHP 7: Return type declarations

    PHP 7: Return type declarations

    opened by findli 5
Open source social sign on PHP Library. HybridAuth goal is to act as an abstract api between your application and various social apis and identities providers such as Facebook, Twitter and Google.

Hybridauth 3.7.1 Hybridauth enables developers to easily build social applications and tools to engage websites visitors and customers on a social lev

hybridauth 3.3k Dec 23, 2022
This library extends the 'League OAuth2 Client' library to provide OpenID Connect Discovery support for supporting providers that expose a .well-known configuration endpoint.

OpenID Connect Discovery support for League - OAuth 2.0 Client This library extends the League OAuth2 Client library to provide OpenID Connect Discove

null 3 Jan 8, 2022
Kaiju is an open source verification bot based on Discord's OAuth written in C# and PHP, with the functionality of being able to integrate the user to a new server in case yours is suspended.

What is Kaiju? Kaiju is an open source verification bot for Discord servers, based on OAuth and with permission for the server owner, to be able to mi

in the space 10 Nov 20, 2022
A free and open-source Automatic Account Creator (AAC) written in PHP

MyAAC MyAAC é um Automatic Account Creator (AAC) gratuito e de código aberto escrito em PHP. É uma bifurcação do projeto Gesior. Ele suporta apenas ba

Lucas Giovanni 6 Aug 26, 2022
EvaOAuth provides a standard interface for OAuth1.0(a) / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few lines code.

EvaOAuth EvaOAuth provides a standard interface for OAuth1.0 / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few

AlloVince 256 Nov 16, 2022
EvaOAuth provides a standard interface for OAuth1.0(a) / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few lines code.

EvaOAuth EvaOAuth provides a standard interface for OAuth1.0 / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few

AlloVince 261 Jan 17, 2022
KeyAuth is an open source authentication system with cloud-hosted subscriptions available aswell

KeyAuth is an open source authentication system with cloud-hosted subscriptions available aswell

null 158 Dec 23, 2022
Automatically fill in the captcha code in the NTHU OAuth login page.

NTHU-OAuth-Decaptcha Automatically fill in the captcha code in the NTHU OAuth login page. CNN Decaptcha For training the decaptcha model. See CNN Deca

null 18 Dec 4, 2022
How to create a simple auth system with login and signup functionalities in Code-igniter 4.

Codeigniter 4 Authentication Login and Registration Example Checkout the step-by-step tutorial on: Codeigniter 4 Authentication Login and Registration

Digamber Rawat 7 Jan 9, 2023
A complete Login and Register page using a Mysql Database and php

Login With Mysql A complete Login and Register page using a Mysql Database ?? Built with ⚙️ ?? Description A login with Frontend, Backend and Database

Marc Medrano 1 Nov 5, 2021
PHP server built using laravel framework.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Lee 0 Dec 27, 2021
php database agnostic authentication library for php developers

Whoo Whoo is a database agnostic authentication library to manage authentication operation easily. Whoo provides you a layer to access and manage user

Yunus Emre Bulut 9 Jan 15, 2022
Limit access to your Laravel applications by using invite codes

Doorman Doorman provides a way to limit access to your Laravel applications by using invite codes. Invite Codes: Can be tied to a specific email addre

Ashley Clarke 964 Dec 31, 2022
Set up Laravel Auth guards using Eloquent in seconds

Nightguard Set up Auth guards using Eloquent in seconds. Introduction Laravel guards provide a super convenient way of authorizing different areas of

Luke Downing 10 Mar 18, 2021
A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package

laravel-social A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package. I

Sergi Tur Badenas 42 Nov 29, 2022
Login Using Laravel UI

Projeto Laravel utilizando a biblioteca Laravel UI para autenticação de usuários com Username e Senha.

AlexLeonel 2 Oct 27, 2021
This is a basic Oauth2 authorization/authentication server implemented using Mezzio.

Mezzio-OAuth2-Authorization-Authentication-Server This is a basic OAuth2 authorization/authentication server implemented using Mezzio. I have found so

null 1 Nov 15, 2022
Login & Register using laravel 8

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Georgy Octavianus Fernando 1 Nov 16, 2021
this is a semester project using Laravel, this app allow user to keep and shear their note with other users.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Vichhagar Nhin 0 Dec 24, 2021