6

I'm attempting to open up data from a PHP Object (as shown below) but I'd like to be able to access this data within JavaScript to use in a graphing library.

Object in question:

http://puu.sh/eP3QZ/e4289eb0d8.png

What I need to be able to do is convert that into a JSON encoded object for use within Javascript.

I tried using twig within Symfony to do this via:

{% set playerStats = match.getStatsPlayers().getValues() }%
{% dump(playerStats) %} // This is what you see above

var playerStats = {{ playerStats|json_encode }};

console.log(playerStats);

The console shows this:

http://puu.sh/eP4aX/adf6c9978f.png

Which is where I'm banging my head against the wall. Where can I access the values of these properties?

As an inefficient way, I've managed to get it into a JavaScript object by doing:

{% for p in playerStats %}
    playerStats.push({ 'id': {{p.playerID}}, 'playerName': '{{p.playerName}}', 'playerOutfit': {{p.playerOutfit}}, 'playerFaction': {{p.playerFaction}}, 'playerKills': {{p.playerKills}}, 'playerDeaths': {{p.playerDeaths}}, 'playerTeamKills': {{p.playerTeamKills}}, 'playerSuicides': {{p.playerSuicides}} });
{% endfor %}

I feel kinda dirty for doing that. There must be a better way to do this surely?

Thanks in advance!

1 Answer 1

8

You can use the Symfony Serializer. http://symfony.com/doc/current/components/serializer.html

You might want to write your own Twig extension to do this from within your template.

Your code will look something like this:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$encoders = array(new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());

$serializer = new Serializer($normalizers, $encoders);

$jsonContent = $serializer->serialize($object, 'json');

When you put that string into your javascript, you should have a normal JS object where you can find everything you want.

You might want to use the JMSSerializerBundle, as it already has a Twig extension, and is easier to use in general.

https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst


An update to give a quick overview of what is in the comments.

Both the Symfony Serializer as the JMSSerializerBundle seem to have a hard time coping with Bi-directional relations (most likely Doctrine). This will result in errors like "Out of memory" or something mentioning "Self-referencing" objects / infinite loops.

To solve this, you can ignore the attribute with the Normalizer. Which will look something like:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$normalizer = new GetSetMethodNormalizer();
$normalizer->setIgnoredAttributes(array('match')); //Replace match with the parent attribute
$encoder = new JsonEncoder();

$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($object, 'json');
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks for the reply. I tried using the JMSSerializerBundle, using the following: var playerStats2 = {{ match.getStatsPlayers().getValues() | serialize('json') }} console.log(playerStats2); All I get unfortunately is a nginx error saying that the app ran out of memory.
Also tried using the symfony serializer. Got "A circular reference has been detected (configured limit: 1)." when trying to seralize this: $em = $this->getDoctrine()->getManager(); $match = $em->getRepository('PSBAdminBundle:Matches')->find($matchID); $statsPlayers = $match->getStatsPlayers()->getValues(); $encoders = array(new JsonEncoder()); $normalizers = array(new GetSetMethodNormalizer()); $serializer = new Serializer($normalizers, $encoders); $jsonContent = $serializer->serialize($statsPlayers, 'json');
What is your ->getValues() actually returning? You might want to ignore entity references to the parent, to see if that solves anything? $normalizer = new GetSetMethodNormalizer(); $normalizer->setIgnoredAttributes(array('match')); Also check the documentation for the setIgnoredAttributes.
The getValues() returns an ArrayCollection, (puu.sh/eP3QZ/e4289eb0d8.png). Would that change anything?
I think it might work when you ignore the 'match' attribute on each StatsPlayer when serializing it. (So you would have to serialize each object on it's own.) It might very well be that the serializer is trying to serialize the match object, which then will try to serialize all the StatsPlayer objects, creating in infinite loop.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.