Industrial-strength annotations for PHP

Overview

php-annotations

Join the chat at https://gitter.im/php-annotations/php-annotations Build Status Scrutinizer Quality Score Code Coverage

Latest Stable Version Total Downloads Latest Unstable Version License

Source-code annotations for PHP.

Copyright (C) 2011-2015 Rasmus Schultz [email protected]

https://github.com/php-annotations/php-annotations

For documentation and updates, please visit the project Wiki:

http://php-annotations.readthedocs.org/

Project Structure

The files in this project are organized as follows:

php-annotations         This README and the LGPL license
  /src
    /annotations        The core of the library itself
      /standard         Standard library of annotation classes
  /demo                 Browser-based example/demonstration
  /docs                 Documentation files (http://php-annotations.readthedocs.org/en/latest/)
  /test                 Unit tests for the core of the library
    /test.php           Test suite runner
    /annotations        Fixture Annotation types
    /lib                Unit test library
    /runtime            Run-time cache folder used for tests
    /suite              Test cases

The "mindplay" folder is the only folder required for the annotation framework itself - other folders contain demonstration code, tests, etc.

To run the test suite, run "php-annotations/test/test.php" from a browser - a summary of the test-results will be displayed on the page.

Code Style

Largely PSR-2 compliant:

https://raw.github.com/php-fig/fig-standards/master/accepted/PSR-2-coding-style-guide.md

License

http://www.gnu.org/licenses/lgpl-3.0.txt

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, see http://www.gnu.org/licenses.

Additional permission under GNU GPL version 3 section 7

If you modify this Program, or any covered work, by linking or combining it with php-annotations (or a modified version of that library), containing parts covered by the terms of the LGPL, the licensors of this Program grant you additional permission to convey the resulting work.

Comments
  • Interpretation of class-names in annotations

    Interpretation of class-names in annotations

    Resolution of type-names in annotations such as @var and @property may be necessary.

    Namespaces were a reasonably new thing when I wrote this library, and the PHP-DOC specification wasn't entirely clear on things like namespace-relative class-name references, e.g.:

    namespace Foo;
    
    use Wham\Baz;
    
    class Bar 
    {
        /**
         * @var Baz
         */
        public $baz;
    }
    

    Does this annotation refer to \Baz, \Foo\Baz or \Wham\Baz ? We know the latter is the answer, but it's dependent on namespace resolution rules, which, at the time, it wasn't clear if those applied to type-names in annotations. I used to write out annotations as @var Wham\Baz not knowing that namespace-resolution rules would apply to type-names in annotations like they do to source-code.

    I think solving this is probably not "low-hanging fruit" - it would require some kind of extension to the API as such, to provide annotations with some means of resolving class-names found in various annotations. It would also require an extension to the AnnotationParser class, to parse the use clause.

    We should ponder how the mechanics of this is going to work, but off the top of my head, I think we may need to expose the AnnotationParser instance during parsing, via IAnnotationParser::parseAnnotation(), e.g. by changing it's signature from parseAnnotation($value) to parseAnnotation($value, AnnotationParser $parser) - so that annotations can go back to a new method like AnnotationParser::resolveClassName($name) to resolve class-names to fully-qualified class-names, based on namespace and use clauses in the file.

    opened by mindplay-dk 74
  • Fix for PHPDoc Param without type

    Fix for PHPDoc Param without type

    When a PHPDoc has no type defined for a@Param entry it fails trying to get array index 1.

    Ex:

    /**
     * This function does something
     *
     * @param $value
     */
    public static function myFunction($value)
    {
    }
    
    opened by naerymdan 48
  • Trait docblocks

    Trait docblocks

    Given a member or method included from a trait which has an annotation

    <?php
    
    trait TestTrait
    {
        /**
         * @var SomeType
         */
        public $member;
    }
    
    class Test {
         use TestTrait;   
    }
    

    php-annotations will fail to detect the annotation on $member. This makes traits almost entirely useless if you need to annotate a trait member! [PHPUnit annotations handle this correctly, FWIW.]

    I've included a failing test case for this in the first commit and a patch in the second. I realize the patch is unlikely to be accepted in its current form, since it introduces a dependency on the reflection API and AnnotationParser might be replaced entirely by #60? But food for thought!

    opened by benesch 34
  • Store documentation not in the Wiki

    Store documentation not in the Wiki

    The GitHub Pages (http://pages.github.com/) is far more superior project website generation tool then the GitHub Wiki (https://github.com/gollum/gollum powered).

    I recommend to use it.

    opened by aik099 23
  • Doubtful code in the

    Doubtful code in the "AnnotationManager::applyConstrains" method

    The AnnotationManager::applyConstrains method designed to validate and filter given annotations list according to @usage annotation of annotations present in given annotations list (filter annotations based on annotation, tricky).

    Problem No. 1 Line 340: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/AnnotationManager.php#L340

    if (!$usage->$member) {
        throw new AnnotationException("{$type} cannot be applied to a {$member}");
    }
    

    Looking at parent Annotation class we can see that there is __get method there, that will throw exception with ... is not a valid property name message when somebody will try accessing non-existing property of the UsageAnnotation. I bet this wasn't desired effect since in such case the nice exception message inside IF will never be thrown. Even if the __get method wasn't there check is still bad, since it doesn't validate if property with given name exists in that class. I recommend using !property_exists($member, $usage)` instead.

    Problem No. 2 Line 344: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/AnnotationManager.php#L352

    if (!$usage->multiple) {
        foreach ($annotations as $inner => $other) {
            if ($inner >= $outer) {
                break;
            }
    
            if ($other instanceof $type) {
                if ($usage->inherited) {
                    unset($annotations[$inner]);
                } else {
                    throw new AnnotationException("only one annotation of type {$type} may be applied to the same {$member}");
                }
            }
        }
    }
    

    The $annotations variable contains annotations that are defined on this property/class/method along with annotations inherited from this property/class/method from the parent class. I understand that finding another annotation of same type on that property/class/method is an exception.

    However, what I do not understand is what if ($usage->inherited) { and unsetting of inner annotations does. Maybe idea was to unset annotations that came from parent classes and only count ones, that are defined in inspected class. However the $usage->inherited doesn't really tell that inspected annotation came from parent class. It only tells that the annotation could came from parent class.

    There is no test, that covers that unset, so I'm wondering what is the logic behind it.

    opened by aik099 21
  • Allow getting annotation name from class name

    Allow getting annotation name from class name

    The last line (of code below) introduces getShortName method (can decide better name of course), that would return annotation name, that was found in DocBlock (e.g. @var, @find-by, etc.).

    Right now I already can filter annotations being returned by Annotations::ofProperty by specifying @var (and others) in $type parameter of that method.

    // 1. create annotation (file1.php)
    namespace RepkaQA\PageObject;
    
    use Mindplay\Annotation\Annotation;
    
    class FindByAnnotation extends Annotation { ... }
    
    // 2. register annotation (file2.php)
    Annotations::getManager()->registry['find-by'] = 'RepkaQA\PageObject\FindByAnnotation';
    
    // 3. use annotation (file2.php)
    $annotations = Annotations::ofProperty($property);
    
    foreach ($annotations as $annotation) {
        $short_name = $annotation->getShortName(); // NEW
    }
    
    opened by aik099 15
  • Exception reading class Annotations from class extending ArrayObject

    Exception reading class Annotations from class extending ArrayObject

    Hi,

    This problem will prob. occur with every class that extends a PHP-Class which has no source.

    
    class TestClass extends ArrayObject
    {
    }
    
    $annotation_manager->getClassAnnotations('TestClass', 'some-annoation');
    

    Will result in an exception trying to read the source file for ArrayObject.

    AnnotationManager.php

    $reflection = new ReflectionClass($class_name);
    $file = $this->getAnnotationFile($reflection->getFileName());
    

    getFileName() returns false which results later in using file_get_contents called with false which throws an exception.

    type-bug 
    opened by evangelion1204 13
  • slash before php global functions

    slash before php global functions

    as agreed... To prevent php from searching for the function in the current namespace. Logically, I only added slashes, so I did not ruin the PSR2 compliance.

    opened by jcheron 12
  • Nested annotation support/need

    Nested annotation support/need

    Some annotation libraries for PHP supports nested annotations in form

    @Block(@FindBy('xpath' => '//test'))
    

    Will it work in this library? Any pros/cons on using nested annotations?

    opened by aik099 12
  • Don't use output parameters in

    Don't use output parameters in "AnnotationManager::applyConstraints" method

    The presence of output parameters (ones that have "&" in them in method declaration) is bad practice.

    I propose that we change the AnnotationManager::applyConstraints(array &$annotations, $member) method to return filtered annotation array instead of reducing one given in 1st parameter.

    opened by aik099 11
  • Attempt to introspect interface/trait fails

    Attempt to introspect interface/trait fails

    When I try to get annotations from an interface/trait then I'm getting exception from the getClassAnnotations method (see https://github.com/php-annotations/php-annotations/blob/master/src/annotations/AnnotationManager.php#L450-L452).

    Even though a ReflectionClass instance is accepted the class_exists check follows which ends all the fun.

    I think that we should allow interfaces/traits in as well.

    type-bug 
    opened by aik099 11
  • Deprecate or retire project?

    Deprecate or retire project?

    Since PHP 8 introduces attributes, the future justification for this project is probably in question.

    I've already voiced this thought to @aik099 who largely took over development after me, and he basically agreed.

    I basically have one reservation about retiring this project.

    There is one feature this project has that you don't get with PHP 8 attributes, and that's the doc-block syntax. Sometimes, you have doc-blocks that are there for two reasons: both for documentation, and for a piece of code to pick it up.

    So if you still need doc-blocks for certain things, there's a chance you could end up having to duplicate certain information between a doc-block for documentation purposes, and an attribute for run-time purposes.

    Probably the best example is things like @param, @type and @return annotations, but with the introduction of e.g. return-types and typed properties since the inception of this project, this may have limited usefulness as well.

    So, is there still a reason for this project to exist?

    If yes: likely this project needs to actually support PHP 8 attributes, so you would get both types of annotations from a single function-call. (Note that this is not what was recently introduced, which is just compatibility with PHP 8, which you can rely on while transitioning to attributes.)

    If no: likely the project is ready to officially retire.

    Note that I don't use annotations (or attributes) myself, so I have no interest in pursuing future development of this project either way. The project gets ~1500 installs/month, about half of which is from @aik099's QA-tools project, so I figured I'd ask the community to comment before officially retiring the project, since it doesn't sound like @aik099 intends to maintain it either.

    If someone else is interested in taking over, I'd be happy to hand it off as well.

    opened by mindplay-dk 0
  • Cache concurrency issue

    Cache concurrency issue

    I experienced hard-to-reproduce errors in an app that uses php-annotations. Looks like the problem is that php-annotations cache cannot handle some concurrency scenarios.

    Simplified caching workflow is: check if entity is in the cache (check if cached file exists) a. if file exists, a.1 include the file. a.2. end of workflow b. if file doesn't exist, b.1. create empty cache file b.2. lock the file b.3. write cache data b.4. end of workflow

    Now consider that the cache is empty & we make two almost simultaneous requests that cause creation of the same cache entities.

    Request I:

    1. check if cached file exists (no)
    2. create empty cache file
    3. lock the file (the file is still empty) ...

    Request II

    1. check if cached file exists (yes)
    2. include the file (but the file is still empty)

    The solution can be to write to temp file, and then move it into the cache.

    opened by ambienthack 4
  • Figure out why HHVM builds are failing

    Figure out why HHVM builds are failing

    Due changes on HHVM/Travis CI the HHVM builds are failing with this message:

    HHVM is no longer supported on Ubuntu Precise. Please consider using Trusty with `dist: trusty`.
    

    See https://travis-ci.org/php-annotations/php-annotations/jobs/244611235

    opened by aik099 1
  • Warning, when reading annotations from dynamically created class

    Warning, when reading annotations from dynamically created class

    When class is created using eval(...) then $reflection->getFileName() (in \mindplay\annotations\AnnotationManager::getAnnotations method) would return something similar to: /path/to/file/with/eval_statement.php(16) : eval()'d code.

    That in turn would result in following warning, when the \mindplay\annotations\AnnotationParser::parseFile method tried to get annotations from it:

    file_get_contents(/path/to/file/with/eval_statement.php(16) : eval()'d code): failed to open stream: No such file or directory
    

    Proposing to check for eval()'d code string in reflected class filename and if found consider it as internal class for which we can't get any annotations.

    type-bug 
    opened by aik099 0
  • Standalone version of demo

    Standalone version of demo

    PSR4 AutoLoader and version of index.html that uses it rather than composer. standalone.php has the same wiki-doc.php profile as index.php. (Compare with index.html to see differences which would be difficult to make optional)

    type-feature state-pending-changes 
    opened by lsces 6
  • Change links to ReadTheDocs to IO domain

    Change links to ReadTheDocs to IO domain

    I've got an e-mail from ReadTheDocs today, that all readthedocs.org sub-domains now should be readthedocs.io sub-domain. They will redirect automatically, but we need to fix links by ourselves anyway.

    opened by aik099 0
Releases(1.3.3)
  • 1.3.3(Jul 16, 2022)

  • 1.3.2(Jan 21, 2021)

    You most likely want to move to attributes, but this release hopefully provides relief for those who wish to migrate gradually or stay with this library for other reasons.

    Thanks for @jcheron for this contribution.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Jan 15, 2019)

    Added

    • Added missing "RangeAnnotation" to demo script by [@lsces].
    • Added "PropertyAnnotation" implementation by [@jcheron].

    Changed

    • Added slash added before PHP global functions to improve namespace resolution speed by [@jcheron].
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Feb 14, 2016)

    Added

    • Run tests on PHP 7 as well.
    • Trait property/method annotations are accessible as part of class annotations by [@benesch].
    • Allow trait introspection for annotations by [@benesch].

    Fixed

    • The root namespace importing (e.g. "use PDO;") wasn't working by [@benesch].
    • Tests, that trigger notices/warnings were marked as passing by [@benesch].
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jun 30, 2015)

    Added

    • Added support for Composer.
    • The namespaced data types (e.g. in "@var" or "@return" annotations) are now supported.
    • Added "IAnnotationFileAware" interface to allow annotations accessing other data (e.g. namespace name) of file it was used in.
    • Added Scrutinizer CI integration.
    • Added Travis CI integration.
    • Added support for "@type" annotation.
    • Added support for "@stop" annotation to prevent from getting annotations from parent class.
    • Added Gitter bagde.
    • Documentation moved from Wiki to ReadTheDocs.

    Changed

    • Main namespace renamed from "Mindplay\Annotation" to "mindplay\annotations".
    • Annotation cache format changed. Need to delete existing cache manually.
    • Improved error message, when attempt get annotations from trait/interface is made.
    • Indexes in returned annotation array are now sequential.
    • Improved exception messages.

    Fixed

    • The "type" in "@var" annotation was always lowercased.
    • The leading "" wasn't stripped from class name given to "getClassAnnotations", "getMethodAnnotations" and "getPropertyAnnotations" methods.
    • Don't attempt to get annotations from internal classes (e.g. "SplFileInfo").
    • Attempt to read annotations from non-existing class properties now ends up in exception.
    • Don't throw exception, when either of these annotations are encountered: "@api", "@source", "@version".
    • No PHP notice is triggered, when malformed (no type) "@param" annotation is being used.
    • Inline annotations (e.g. "// @codeCoverageIgnore") were processed by mistake.

    Removed

    • Standard annotation stubs (e.g. "@display", "@format", "@length", etc.) were removed.
    • Removed incomplete support for "@usage" annotation inheritance.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Feb 14, 2016)

    Changed

    • Cache engine rewritten from scratch to increase performance.
    • Renamed protected "Annotation::_map" method into "Annotation::map" method.
    • Annotation cache format changed. Need to delete existing cache manually.
    • Don't write trailing ";" to cache files.

    Removed

    • Removed APC support in caching layer.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Feb 14, 2016)

Owner
php-annotations
Industrial-strength annotations for PHP
php-annotations
Yii2 Annotations Generate API Document Extension

Generate online api document by code annotation for yii2 easily

Trevor 16 Dec 15, 2021
Generate interactive OpenAPI documentation for your RESTful API using doctrine annotations

Generate interactive OpenAPI documentation for your RESTful API using doctrine annotations

Robert Allen 4.6k Jan 6, 2023
PHP 7.1 ready Smart and Simple Documentation for your PHP project

Smart and Readable Documentation for your PHP project ApiGen is the simplest, the easiest to use and the most modern api doc generator. It is all PHP

ApiGen 2.1k Dec 22, 2022
PHP 7.1 ready Smart and Simple Documentation for your PHP project

Smart and Readable Documentation for your PHP project ApiGen is the simplest, the easiest to use and the most modern api doc generator. It is all PHP

ApiGen 2.1k Apr 20, 2021
Learn how to implement the most important Design Patterns into your PHP application, uses PHP 8.1

Learn how to implement the most important Design Patterns into your PHP application. This project uses PHP 8.1. it has examples for each Pattern and an Article explaining how to use them step by step, their advantages, and disadvantages.

Gabriel Anhaia 203 Dec 15, 2022
Documentation Generator for PHP

phpDocumentor What is phpDocumentor? phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to genera

phpDocumentor 3.7k Dec 28, 2022
Documentation generator for PHP Code using standard technology (SRC, DOCBLOCK, XML and XSLT)

phpDox phpDox is a documentation generator for PHP projects. This includes, but is not limited to, API documentation. The main focus is on enriching t

Arne Blankerts 588 Dec 22, 2022
A php API documentation generator, fork of Sami

Doctum, a PHP API documentation generator. Fork of Sami Curious about what Doctum generates? Have a look at the MariaDB MySQL Kbs or Laravel documenta

Code LTS 203 Dec 21, 2022
Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and / or RESTful API

Luracast Restler ![Gitter](https://badges.gitter.im/Join Chat.svg) Version 3.0 Release Candidate 5 Restler is a simple and effective multi-format Web

Luracast 1.4k Jan 2, 2023
A PHP framework foucs on API fast development.接口,从简单开始!PhalApi简称π框架,一个轻量级PHP开源接口框架,专注于接口服务开发。

PhalApi开源接口框架 / PhalApi API Framework 读音:派框架 Stargazers over time 开发文档 / Documents 专为PHPer准备的优雅而详细的开发文档,请看:PhalApi 2.x 开发文档。 PhalApi 2.x English Docs.

dogstar 1.5k Dec 30, 2022
30 seconds of code Short PHP code snippets for all your development needs

30 seconds of code Short PHP code snippets for all your development needs Visit our website to view our snippet collection. Use the Search page to fin

30 seconds of code 2.5k Jan 1, 2023
Source Code for 'PHP 8 Solutions' by David Powers

Apress Source Code This repository accompanies PHP 8 Solutions by David Powers (Apress, 2022). Download the files as a zip using the green button, or

Apress 8 Oct 27, 2022
PHP Developer Roadmap

This is PHP Developer Roadmap

TheCodeholic 2.3k Jan 6, 2023
phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to generate a complete set of API Documentation

phpDocumentor What is phpDocumentor? phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to genera

phpDocumentor 3.7k Jan 3, 2023
PhpMetrics provides metrics about PHP project and classes, with beautiful and readable HTML report.

PhpMetrics provides metrics about PHP project and classes, with beautiful and readable HTML report.

PhpMetrics 2.3k Jan 5, 2023
Realistic PHP password strength estimate library based on Zxcvbn JS

Zxcvbn-PHP is a password strength estimator using pattern matching and minimum entropy calculation. Zxcvbn-PHP is based on the the Javascript zxcvbn p

Ben Jeavons 767 Dec 15, 2022
Quickly and easily expose Doctrine entities as REST resource endpoints with the use of simple configuration with annotations, yaml, json or a PHP array.

Drest Dress up doctrine entities and expose them as REST resources This library allows you to quickly annotate your doctrine entities into restful res

Lee Davis 88 Nov 5, 2022
:tada: Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)

HTTP router for PHP 7.1+ (incl. PHP 8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger) Installation compo

Sunrise // PHP 151 Jan 5, 2023
This library can parse a TypeSchema specification either from a JSON file, or from PHP classes using reflection and annotations.

This library can parse a TypeSchema specification either from a JSON file, or from PHP classes using reflection and annotations. Based on this schema it can generate source code and transform raw JSON data into DTO objects. Through this you can work with fully typed objects in your API for incoming and outgoing data.

Apioo 54 Jul 14, 2022
Simple and Lightweight PHP Class & Methods Annotations Reader

README Simple and Lightweight PHP Class & Methods Annotations Reader Forked from eriknyk/Annotations 项目地址 github https://github.com/phppkg/annotations

PHPPkg 3 Nov 25, 2021