Code Monkey home page Code Monkey logo

metadata's Introduction

Metadata is a library for class/method/property metadata management in PHP

Master (2.x) 1.x
Build status Build status
Coverage Status Coverage Status

Overview

This library provides some commonly needed base classes for managing metadata for classes, methods and properties. The metadata can come from many different sources (annotations, YAML/XML/PHP configuration files).

The metadata classes are used to abstract away that source and provide a common interface for all of them.

Usage

The library provides three classes that you can extend to add your application specific properties, and flags: ClassMetadata, MethodMetadata, and PropertyMetadata

After you have added, your properties in sub-classes, you also need to add DriverInterface implementations which know how to populate these classes from the different metadata sources.

Finally, you can use the MetadataFactory to retrieve the metadata::

<?php
    
use Metadata\MetadataFactory;
use Metadata\Driver\DriverChain;

$driver = new DriverChain(array(
    /** Annotation, YAML, XML, PHP, ... drivers */
));
$factory = new MetadataFactory($driver);
$metadata = $factory->getMetadataForClass('MyNamespace\MyObject');

metadata's People

Contributors

adrienbrault avatar aliance avatar bakura10 avatar bobvandevijver avatar dbu avatar flip111 avatar gam6itko avatar goetas avatar gusdecool avatar hason avatar henrikbjorn avatar jlekowski avatar mbabker avatar nicolas-grekas avatar nyholm avatar pdugas avatar peter279k avatar ruudk avatar samnela avatar schmittjoh avatar seldaek avatar stof avatar thepanz avatar thomasnunninger avatar tobilektri avatar tobion avatar tommygnr avatar valiodotch avatar vicb avatar w0rma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metadata's Issues

RFC: Lazy instantiation and unification of reflection classes in MethodMetadata and PropertyMetadata

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? yes

As far as I see it, there is an inconsistency in MethodMetadata and PropertyMetadata:

  • MethodMetadata::__construct() (and ::unserialize()) instantiate a ReflectionMethod. Additionally the class offeres an invoke() method

  • PropertyMetadata does not have such behavior and does not create a reflection class.

I see two problems:

  • The behavior is inconsistent
  • On each unserialize of a class, a ReflectionMethod is created for each method. This costs time.

Proposal

I assume, it would have been best not to provide the $reflection property in MethodMetadata at all. But you can't remove it for now as that would be a BC break. Therefore I propose:

  • Lazy-initialize a ReflectionMethod only if needed and save it internally for later reuse.
  • Make MethodMetadata->reflection private and provide a __get() that handles this case.
  • Implement similar behavior for PropertyMetadata.

Questions

  • Is such a change desired?
  • Would you accept a pull request?

create version/tag 1.1.1

now after composer.json was added for packagist.org it would be great, if you create a new version which contains this file, so it could get referenced from other packages.

(this alredy happens, but the dependency is broken, because of a missing release matching the 1.1.* version pattern)

Change license to MIT

In order to change the license on this project, we have to get the approval of every past contributor. At the time of writing this we have had 17 contributors.

If you are reading this and you are a contributor on the below list, please reply to this GitHub issue with the following text:

I, @username, agree to license my contributions to the schmittjoh/metadata project from the Apache-2.0 to the MIT license effective immediately.

`jms/metadata 2.6.0` seems to be incompatible with `jms/serializer 3.15.0`

Q A
Bug report? yes
Feature request? no
BC Break report? yes
RFC? no

Steps required to reproduce the problem

  1. Use jms/metadata 2.6.0 with jms/serializer 3.15.0,
  2. Deserialize an annotated object

Note that on the first request it works fine, but it breaks on the second request indicating it is a cache problem. Looking at what happens, it looks like the PropertyMetadata is used in the serializer, which has indeed received a BC breaking change looking at the upgrading docs (not sure why it mentions from 2.0 to 2.3 though).

I believe 2.6 should have been released as a 3.0 version, indicating this major BC break for all consumers using the PropertyMetadata, or maybe the intended BC compatibility layer isn't working as expected?

Expected Result

  • Correct retrieval of class metadata

Actual Result

  • The meaningful properties of the metadata are all null.

Error in Symfony2's production environment (only) caused with version >= 1.4.0

After an upgrade from 1.3.0 to 1.4.0 (or 1.4.1, tried both), the exception added in this commit f68e2a8 is thrown whenever I access one of the pages of my website (but not all of them). It happens only with app.php (not app_dev.php / app_test.php).

Here's the stacktrace :
[2013-09-03 14:59:50] request.CRITICAL: Uncaught PHP Exception LogicException: "The cache must return instances of ClassMetadata, but got false." at /var/www/xxx/vendor/jms/metadata/src/Metadata/MetadataFactory.php line 81 {"exception":"[object] (LogicException: The cache must return instances of ClassMetadata, but got false. at /var/www/xxx/vendor/jms/metadata/src/Metadata/MetadataFactory.php:81)"} []

I've reverted the library to 1.3.0 temporarily, but would very much like to see this resolved. Thanks for your help.

Read-Only Filesystem Support

When deploying a Symfony 4 app that uses JMS Serializer (and thus Metadata) to a Docker container or other platform where a read-only filesystem is desirable, the Metadata\Cache\FileCache is causing problems. I'm using the recently added feature in Serializer to warmup the cache so these files don't need to be written once deployed. However, there is an is_writeable() test on the cache directory still. I propose taking that test out of FileCache::__construct() and adding adding it back in the putClassMetadataInCache() method.

Composer.lock is out of date

$ php -a
php > echo json_decode(file_get_contents('composer.lock'))->hash;
ad3268b8f0919dace5b4464268d6b1dc
php > echo md5(file_get_contents('composer.json'));
96d5f0475c298187cc5bb9919ef666ed

Dynamic Properties Created

Q A
Bug report? no
Feature request? no
BC Break report? no
RFC? no

Running the test suite locally on PHP 8.2 (which isn't covered in CI right now) with #113 gives this output:

$ vendor/bin/phpunit 
PHPUnit 9.6.10 by Sebastian Bergmann and contributors.

Warning:       Your XML configuration validates against a deprecated schema.
Suggestion:    Migrate your XML configuration using "--migrate-configuration"!

SS................................................WPHP Deprecated:  Creation of dynamic property Metadata\MethodMetadata::$unknownProperty is deprecated in /Users/mbabker/Sites/metadata/src/MethodMetadata.php on line 68
.
Deprecated: Creation of dynamic property Metadata\MethodMetadata::$unknownProperty is deprecated in /Users/mbabker/Sites/metadata/src/MethodMetadata.php on line 68
..

Time: 00:04.136, Memory: 8.00 MB

There was 1 warning:

1) Metadata\Tests\MethodMetadataTest::testReadAccessForUnknownProperty
Expecting E_WARNING and E_USER_WARNING is deprecated and will no longer be possible in PHPUnit 10.

WARNINGS!
Tests: 55, Assertions: 117, Warnings: 1, Skipped: 2.

The PHPUnit deprecation can be dealt with at a later point as it only affects the testing environment, but the dynamic property creation in the Metadata\MethodMetadata class introduced via #78 should be reviewed at some point.

install version 1.0.0 with composer

Hello,

when running composer.phar require jms/metadata:1.0.*@stable or composer.phar require jms/metadata:1.0.0 I get an error like the version is not available, but on your git account tag 1.0.0 exists... I have no idea, do you?

cheer ;)

Extending Metadata not possible?

Q A
Bug report? no
Feature request? no
BC Break report? yes
RFC? no

From the readme:

The library provides three classes that you can extend to add your application specific properties, and flags: ClassMetadata, MethodMetadata, and PropertyMetadata

Correct me if I'm wrong, but it looks return types break the idea of extending those classes. See dustin10/VichUploaderBundle#918 (comment).

Best way of handling dependent metadata

Hi,

I've came across the following use case and I'm not sure about how to solve it correctly : when I load a class metadata (for instance in loadMetadataFromFile for FileDriver), I need to get data defined by mapping that can possibly be defined by another file driver.

I then use the DriverChain. The problem is how to solve that? I've thought first to create the class metadata, and inject the class metadata into the different drivers so that I have access to it in the loadMetadataFromFile. The problem of course is that I need first to construct the drivers...

The second solution I've found is construct all the drivers, then create the class metadata, and then iterate through the drivers again and call a setter to set the class metadata factory.

What is the best way for that?

EDIT : In fact I think the best way is to create the FileDriverLocator to have all the dirs. So it's easier then.

EDIT 2 : but this won't solve the problem if people use both annotation and file drivers. So I still need to inject it to some point.

Thanks for your help !

RFC: Private visibility on MetadataFactory

Would you consider merging a PR that increased the visibility of a few parts of MetadataFactory from private to protected? (It wouldn't necessary have to become part of the stable API - but allowing overriding of parts of the MetadataFactory will prevent me having to copy/paste large parts of it.)

My use case:

  • I'm trying to prevent a few round trips to the cache caused by a very 'deep' hierarchy of classes, all of which I know will have no metadata (the cache checks are unnecessary)
  • There's nothing overridable in the MetadataFactory that will allow me to short-circuit before the call to check the cache

I've looked into:

  • Adjusting the 'hierarchy' metadata class via constructor parameter
    • This class seems to just hold the results, and won't allow me to filter before incurring the cost of the cache round-trips
  • "Preloading" null metadata entries into the 'loadedMetadata' member array of the factory
    • This would allow the parent classes to be excluded without going to the cache, but the member array is private
  • Overriding getClassHierarchy(), which is probably closest to what I actually want to do
    • This would allow me to filter the hierarchy to the classes I care about, but getClassHierarchy() is private, so this requires copy/paste of about 60 lines - yuck

I can't seem to find a way around this, but if you have an alternative to suggest, I'd be happy to hear it. The long-term fix if you don't want to open up the internal API might be to use a strategy pattern for turning the class name into a hierarchy, so that I can override that part via DI.

More documentation requested

Hi!

From documentation it's not so clear how this library can be used. Can you please update the readme with more information on what this library is targeted to and some more verbose usage examples maybe.

As far as I can see it requires external annotation/xml/yaml/whatsoever reader adapter to get the metadata and those readers must implement some interface which make it necessary to implement it again for each use case but not use the existing Doctrine readers for example.

Does the lib provide the ability to use extra annotations which Doctrine Common's reader does not allow?
Does it cache the metadata information by default and what configuration it requires to make caching work.

It would be nice to have the annotated class as an example together with simple howto work with with it and description on the abstraction layers that this lib provides.

Thanks!

Possible performance issue in 2.1.0

Q A
Bug report? no
Feature request? no
BC Break report? no
RFC? no

Since update of jms/metadata from 2.0.0 to 2.1.0 we are getting these kind of random errors

[2019-09-23 12:22:29] php.CRITICAL: Fatal Error: Maximum execution time of 30 seconds exceeded {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 0): Error: Maximum execution time of 30 seconds exceeded at /var/lib/jenkins/workspace/tsf_calida_PR-7973/shop/vendor/jms/serializer/src/JMS/Serializer/Exclusion/DepthExclusionStrategy.php:39)"} []
[2019-09-23 12:22:29] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalErrorException: "Error: Maximum execution time of 30 seconds exceeded" at /var/lib/jenkins/workspace/tsf_calida_PR-7973/shop/vendor/jms/serializer/src/JMS/Serializer/Exclusion/DepthExclusionStrategy.php line 39 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 0): Error: Maximum execution time of 30 seconds exceeded at /var/lib/jenkins/workspace/tsf_calida_PR-7973/shop/vendor/jms/serializer/src/JMS/Serializer/Exclusion/DepthExclusionStrategy.php:39)"} []

Could it be related to some changes done here?

Big performance hit when upgrading from 1.4.2 to 1.5.0

A few days ago we upgraded a few packages in our SF2 project and realized that our times when from 60 ms to almost 100 ms (confirmed both by newrelic and logstash), so we started to debug which one of the upgrades was to blame.

Finally we've found the cause on the metadata package upgrade from 1.4.2 to 1.5.0. Here's a screenshot of 500 requests with version 1.4.2 vs 500 with version 1.5.0

jms-perf

Taking a look to the differences between 1.4.2 vs 1.5.0 the only possible cause may be the pull request #36 (medatada caching improvement). I see on the issue that a benchmark was done, but I don't know which kind of benchmark and if it was done with "real code". Could it be that the change from one call to instanceof to five (two directly on getMetadataForClass and three more calling filterNullMetadata) is causing this performance hit? It seems that as instanceof uses strings comparisons, the class name length has a big impact, but this is just a guess.

Why 0666 mode for cache file

Hi all,

Someone can tell me why the file cache are 0666 mode, why not 0660 ? why authorized other to read the cache ??

chmod($tmpFile, 0666 & ~umask()); in src / Metadata / Cache / FileCache.php at line 45

My issue is that i run in box with NFS shared in 0660 mode for security.

Thx for explanation

Update from 1.X to 2

Q A
Bug report? no
Feature request? no
BC Break report? no
RFC? yes

I can't find any update-related document in this repository, so I assume that upgrading from 1.X to 2.0 should be painless?
I'm asking because in a bundle of mine we're using 1.X version and planning to support 2.X version too, but some tests are failing.
See dustin10/VichUploaderBundle#918

Caching issue in debug mode when methods are being removed

I'm running into a problem using schmittjoh/metadata in one of our libraries (teqneers/ext-direct) when in debug mode.

Preconditions:
  • \Metadata\MetadataFactory configured with a cache
  • \Metadata\MetadataFactory configured to run in debug mode
  • Direct\Action and Direct\Method are custom annotations
/**
 * @Direct\Action()
 */
class A {
    /**
     * @Direct\Method()
     */
    public function a() {}
    /**
     * @Direct\Method()
     */
    public function b() {}
}

Everything runs fine until we remove one of the two methods:

/**
 * @Direct\Action()
 */
class A {
    /**
     * @Direct\Method()
     */
    public function a() {}
}

Clearly the metadata in the cache is outdated now. \Metadata\MetadataFactory::getMetadataForClass($className) calls $this->cache->loadClassMetadataFromCache($class) in line 82. As data inside the cache is serialized, it'll be unserialized at this point calling \Metadata\MethodMetadata::unserialize() in the process. This in turn runs:

$this->reflection = new \ReflectionMethod($this->class, $this->name);
$this->reflection->setAccessible(true);

which fails because A::b() isn't a valid method any more:

ReflectionException: Method A::b() does not exist

The solution could be to wrap MetadataFactory.php lines 82:85 in a try-catch-block:

try {
    if (($classMetadata = $this->cache->loadClassMetadataFromCache($class)) instanceof NullMetadata) {
        $this->loadedClassMetadata[$name] = $classMetadata;
        continue;
    }
} catch (\ReflectionException $e) {
    // error during unserialze
    $classMetadata = null;   
}

If that's OK, I'd submit a PR.

consider changing chmod to @chmod

I have just run into trouble when using SF2 + JMS Serializer Bundle on vagrant box (windows using SMB).

The thing is that os can't use chmod on shared filesystems and attempt made here:
https://github.com/schmittjoh/metadata/blob/master/src/Metadata/Cache/FileCache.php#L45
breaks the request.

I noticed that in many places Symfony suppresses the error using @chmod so despite general rule that using @ to hide errors is bad I'd consider using it in this case.

I made a workaround to place my cache dir outside the shared folder structure for now but this fix might be handy.

Tons of I/O operations caused by NullMetadata

While troubleshooting my production server performance I found out that metadata library is creating a lot of tmp files and renaming to the same name on every request, as there is no property "name" in NullMetadata class (it serializes to an empty class).

Debug information from FileCache::putClassMetadataInCache:
putclassmetadataincache_debug

Example of operations from fatrace, that are made on every request:

apache2(1048): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheDIwGQx
apache2(1048): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheDIwGQx
apache2(1048): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheDIwGQx
apache2(1048): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachevRV94h
apache2(1048): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(1048): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(2950): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheAggRB7
apache2(2950): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheAggRB7
apache2(2950): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheAggRB7
apache2(2950): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheAggRB7
apache2(2950): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheAggRB7
apache2(2950): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheNwjvdS
apache2(2950): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheNwjvdS
apache2(2950): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(2950): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(983): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachecxFAVB
apache2(983): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachecxFAVB
apache2(983): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachecxFAVB
apache2(983): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachewGC6Tm
apache2(983): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachewGC6Tm
apache2(983): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachewGC6Tm
apache2(2944): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheSVFyEy
apache2(2944): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheSVFyEy
apache2(2944): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheSVFyEy
apache2(2944): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheSVFyEy
apache2(2944): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cacheDuL8Zj
apache2(2944): CWO /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(2944): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/.cache.php
apache2(2983): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachelktGRx
apache2(2983): CW /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachelktGRx
apache2(2983): O /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachelktGRx
apache2(2983): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachelktGRx
apache2(2983): W /home/luxemate/www/gamesite/app/cache/prod/jms_diextra/metadata/metadata-cachelktGRx

Metadata validation

I would like to be able to validate the metadata somehow. This means that I would need to somehow hook into the MetadataFactory so I can validate the my ClassMetadata before it is returned by getMetadataForClass.

I cannot do this in the driver because ClassMetadata needs to be merged before it is validated. There seems to way to hook into the MetadataFactory after the class hierarchy metadata has been merged.

TypeError when trying to cache anonymous class

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? yes

I understand if instances of anonymous classes are not meant to be serialized or cached, but if such is provided, an unexpected TypeError is thrown due to null byte issue (https://www.php.net/manual/en/security.filesystem.nullbytes.php).

// same with rename() function
$ php -r 'declare(strict_types=1); file_exists("file.php\0");'
PHP Fatal error:  Uncaught TypeError: file_exists() expects parameter 1 to be a valid path, string given in Command line code:1
Stack trace:
#0 Command line code(1): file_exists('file.php\x00')
#1 {main}
  thrown in Command line code on line 1

See the code lines:
https://github.com/schmittjoh/metadata/blob/master/src/Cache/FileCache.php#L31
https://github.com/schmittjoh/metadata/blob/master/src/Cache/FileCache.php#L64

There are ways to validate path:

  • strpos($class, "\0") !== false
  • ctype_print($class)
  • catch (\TypeError $e)
  • $class->isAnonymous()

or to fix it with str_replace("\0", "", $class).

Eventually the class will not be cached using its name anyway because the name is like class@anonymous/app/src/Controller/CoreController.php0x7f1f4ea446cf. Also, according to the documentation https://www.php.net/manual/en/language.oop5.anonymous.php:

This name has to be regarded an implementation detail, which should not be relied upon.

Steps required to reproduce the problem

In Metadata\Tests\Cache\FileCacheTest add:

    public function testLoadAnonymousClassMetadataFromInCache()
    {
        $cache = new FileCache($this->dir);
        $cache->load(get_class(new class {}));
    }

and run unit tests.

Expected Result

  • TBD (personally I'd see a custom exception, potentially silent fail)

Actual Result

  • TypeError: file_exists() expects parameter 1 to be a valid path, string given

Update changelog

Hi,

Would it be possible to update the change log to see what's new in 1.4.0 ?

Thanks ;-)

Ability to eager-load possible metadata

Granted, this is a terrible idea and slow, I think I came across a use-case where I need this ability (in development of course).

Basically, I'm using the Symfony routing component and want to create routes based off metadata instead of loading all the files and suporting all metadata types in the routing component itself....

ie.)

User:
    name: user
Post:
    name: post
// User.php
/**
 * @SomeAnnotation(name="user")
 */
class User { /** ... */ }

// Post.php
/**
 * @SomeAnnotation(name="post")
 */
class Post { /** ... */ }

I'd create to routes based off the 'name' parameter '/user' and '/post'. I support other drivers too and would rather hook directly into the ClassMetadata::$myName property to get the path name instead of using Yaml::parse and other misc readers twice just to get the one property.

Of course routing will be cached in the end and there wouldn't be a need to eager load all the metadata files...

Or if you can think of a better way, I'm open to suggestions.

Consider switching to the MIT/BSD license or a dual license otherwise

This library is used extensively in the PHP community, but because it's released under the Apache 2.0 license it's incompatible with GPLv2 and therefor cannot be safely used for all projects.

Most PHP libraries actually use the MIT/BSD or LGPL license, which makes it almost strange for this library to use the Apache 2.0 license.

I wonder if you would consider switching to the MIT/BSD license or use dual (Apache 2.0 / GPL) license instead? @schmittjoh

Unexpected return value

I am using this library the first time and the following issue occured: When I use the getMetadataForClass method I get back a hierarchy object (which probably contains all my metadata). To get the actual data I have to do the following:

$metdata = $factory->getMetadataForClass('Class');
$classMetadata = $metadata->classMetadata['Class'];

I think this is a bit weird and a really unfriendly behavior. Am I missing something here or this is the wy it should work. If the latter: why? Can't find any reason which beats the argument of usability.

Branch alias

The changelog list features for 1.5.0, however the current branch alias is 1.4.x ... is it correct ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.