JMSSerializer autonome - Annotation n'existe pas ou ne peut pas être chargé automatiquement

j'essaie d'utiliser JMSSerializer comme une bibliothèque autonome pour mapper les réponses JSON d'une API vers mes classes de model et je suis en train de rencontrer quelques problèmes.

L'exécution du code suivant entraîne une exception:

<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use JMSSerializerAnnotation AS JMS;

class Trii {
    /**
     * User ID for this session
     * @JMSSerializedName("userID")
     * @JMSAnnotation(getter="getUserId")
     * @JMSType("string")
     * @var string
     */
    private $userId;

    public function getUserId() {
        return $this->userId;
    }

    public function setUserId($userId) {
        $this->userId = $userId;
    }
}

$serializer = JMSSerializerSerializerBuilder::create()->setDebug(true)->build();
$object = $serializer->deserialize('{"userID":"Trii"}', 'Trii', 'json');
var_dump($object);
?>

Voici l'exception

DoctrineCommonAnnotationsAnnotationException: [Semantical Error] The annotation "@JMSSerializerAnnotationSerializedName" in property Trii::$userId does not exist, or could not be auto-loaded.

j'ai installé les bibliothèques suivantes pour le projet via composer

{
    "require": {
        "jms/serializer": "1.0.*@dev"
    }
}

y a-t-il quelque chose d'évident qui me manque puisque je n'utilise pas toute la Doctrine 2 la solution?

EDIT: ma solution finale a été de créer un fichier bootstrap avec le contenu suivant:

<?php
// standard composer install vendor autoload magic
require dirname(__DIR__) . '/vendor/autoload.php';

// Bootstrap the JMS custom annotations for Object to Json mapping
DoctrineCommonAnnotationsAnnotationRegistry::registerAutoloadNamespace(
    'JMSSerializerAnnotation',
    dirname(__DIR__).'/vendor/jms/serializer/src'
);
?>
33
demandé sur Josh J 2013-01-31 19:20:44

5 réponses

Je suis sûr que cela permet l'auto-chargement silencieux qui est beaucoup plus pratique que l'enregistrement des espaces de noms vous-même.

AnnotationRegistry::registerLoader('class_exists');
66
répondu Flip 2014-04-10 10:17:44

j'ai rencontré le même problème et J'ai trouvé votre question sur Google. Malheureusement, vous n'aviez pas encore reçu de réponse, alors j'ai dû creuser moi-même. :P

Le truc, c'est la Doctrine des Annotations, qui JMSSerializer Annotations utilise, n'utilise pas L'autoloading PHP normal.

comment ces annotations sont-elles chargées? En regardant le code, vous pouvez deviner que la cartographie ORM, Assert Validation et l'annotation entièrement qualifié peut être chargé en utilisant les autoloaders PHP définis. Ce n'est toutefois pas le cas: pour des raisons de gestion des erreurs, chaque vérification de l'existence d'une classe à L'intérieur de L'AnnotationReader définit le second paramètre $autoload de class_exists($name, $autoload) à false. Pour fonctionner sans problème, le lecteur D'AnnotationReader nécessite des lecteurs automatiques silencieux, ce qui n'est pas le cas de beaucoup de lecteurs automatiques. L'autoloading silencieux ne fait pas partie de la spécification PSR-0 pour l'autoloading.

Cela signifie que vous devez enregistrer le fichier d'Annotation(s) vous-même:

AnnotationRegistry::registerFile(
   <PROJECT ROOT> . 
   "/vendor/jms/serializer/src/JMS/Serializer/Annotation/SerializedName.php");

... ou de l'ensemble de l'espace de noms (méthode préférée):

AnnotationRegistry::registerAutoloadNamespace(
    'JMS\Serializer\Annotation', 
    <PROJECT ROOT> . "/vendor/jms/serializer/src");

attention avec le chemin dans registerAutoloadNamespace. J'ai d'abord essayé d'enregistrer tout le chemin vers les annotations de la même manière avec registerFile:

<PROJECT ROOT> . "/vendor/jms/serializer/src/JMS/Serializer/Annotation 

mais cela a lamentablement échoué. : D

j'espère que cela vous arrive un pas de plus. :)

40
répondu SirArturio 2016-11-16 23:06:47

@SirArturio a la bonne réponse à ce puzzle D'Autoloading, et je voulais juste ajouter un peu plus de clarté en réponse à @messified ou quelqu'un d'autre luttant pour que cela fonctionne. Comme il l'a expliqué avec éloquence, le manipulateur automatique PSR-0 de composer, ou SPL, ne va pas le couper pour charger ces annotations puisqu'il utilise L'autoloading de Doctrine.

voici donc un petit exemple complet. Chaque fois que vous créez votre objet JMS Serializer pour commencer la sérialisation est un bon moment pour ajoutez le namespace d'annotation à Autoloader de doctrine. Par souci de clarté, je suppose qu'il n'y a pas de CIO, et des espaces de noms entièrement qualifiés (indice d'indice, injection de dépendance):

<?php
Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
'JMS\Serializer\Annotation', 
$your_app_basepath . "/vendor/jms/serializer/src");


$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$json_output = $serializer->serialize('MyProject\MyClass', 'json');

puis dans votre MyProject\MyClass:

<?php
use JMS\Serializer\Annotation as JMS;

class MyClass{

    /** @JMS\Exclude */
    private $something_secret;
}

et cela devrait le couper, autoloading le fichier d'annotation approprié en utilisant la doctrine au lieu de compositeur.

4
répondu jpschroeder 2013-11-15 15:53:17

Vérifiez la capitalisation de vos annotations. J'ai eu un problème similaire lors du déploiement à partir D'un environnement Windows dev vers un serveur Ubuntu qui a été causé par une faute de frappe dans le cas de mon annotation. Les fichiers Windows ne sont pas sensibles à la casse, donc ils fonctionnent mais échouent sous Linux.

2
répondu Tamlyn 2013-06-26 14:14:56

Voici la solution

1.aller au répertoire php puis installer compositeur php compositeur-setup.php 2. aller à l'annuaire du projet sdk par exemple,

cd / Applications/XAMPP/xamppfiles/htdocs/streetreturn/adn_sdk-php-master

mettre à jour composer pour installer les dépendances php /Utilisateurs/zakir/compositeur.phar update

* Note:/Users/zakir / composer.phar sera localisé lors de l'installation de composer à l'étape 1

-3
répondu Zakir Hossain 2017-03-02 18:05:30