How to profile code through Symfony StopWatch component - php

As per docs says:
The Stopwatch component provides an easy and consistent way to measure
execution time of certain parts of code so that you don't constantly
have to parse microtime by yourself.
I want to profile my REST API cURL calls and code execution in order to reduce the times but I am not sure how to do this. What I did on my code is put this piece of code:
$stopwatch->start('repsync', 'internal');
// the code goes here
$stopwatch->stop('repsync', 'internal');
But since this is a RESTful API I am not sure how to get profiler results. I was looking at StopWatch and notice getEvent and getSectionEvents but again I am not sure if I should call them directly and past the result to a Monolog logger or there is any other way to achieve this. In a few words: how do I see the profiler results when accessing routes trough a RESTful API? Any advice? Ideas?

This is how I handle it.
Use twig to render your api's data, in your Controller :
return $this->render('MyApiBundle:Default:debug.html.twig', array('data' => $data));
Then create the 'debug' template in Resources/views/Default/debug.html.twig
{% extends 'base.html.twig' %}
{% block body %}
Debug page
{{ dump(data) }}
{% endblock %}
Within your browser, call one of your API GET url. You will access Symfony's profiler and see your data.
For code execution time, you can listen to kernel.request and kernel.terminate events.

Related

Zend expressive - Layout

In my layout (Twig), i'd like to retrieve a value from a Middleware authentication.
If i put, in templates.global.pĥp:
'twig' => [
'globals' => [
// Variables to pass to all twig templates
'auth' => (new \Zend\Authentication\AuthenticationService())->hasIdentity(),
],
],
And in layout default.html.twig
{% if auth %}
Connect
{% else %}
Not connect
{% endif %}
This code works, but, is it a good method ?
Thank you :)
It's not a good method. First of all, using the config files to set global template data is meant for static data. Creating a service in the config will fail if you want to cache the config. I don't know about the zend auction service, but it would be better to get it from the service manager or any other container you are using. This way you make sure that everywhere in your application the same service is being used.
For common variables or services which are needed in templates, I have a wrapper around the TemplateRenderer. So instead of calling the original template renderer, I call my own class and in there I populate the template with common data.
And you can also inject default parameters with TemplateRendererInterface::addDefaultParam. In any other middleware you can inject the templaterenderer, set the desired default data and later on access it in your templates.

Twig include performance with and without passing variables

I am wondering what is best perfomance-wise, using
{% include "_inc/template" %}
or
{% include "_inc/template" with {'foo': bar %}
assuming foo is the only variable used in _inc/template and it's also available in global context.
Will there be significant difference in performance between two approaches, if the include is placed within for having ~50 loops?
I don't have direct answer to your question, but you can use the profiler in dev toolbar to see the timeline of the calls.
Maybe try and tell us...
Which is the version of symfony you use?
I know that in symfony > 2.7 the timeline Graph exist.
Ps : Maybe try it with this too:
{% include 'template.html' with {'foo': 'bar'} only %}

Error pages Symfony2 with locale

I'm trying to translate 404 pages on Symfony2, but it's not working. With 500 error pages it works great.
For example, when i try to access the page: /es/not-found it shows the 404 page, but when i access /en/not-found, it gives me the SAME page, although i have translated the error message on my messages-en.yml.
It seems it's always accessing the messages-es.yml file, because i've configured Symfony with this default locale (es).
If i print {{ app.request.locale }} on my Twig template, it doesn't give me anything.
I cleared the cache several times, yes :).
Thanks in advance!
If the localization configuration is properly working, you should be able to print the locale on Twig. With something like this:
{% if app.request.locale == 'en' %}
English 404 message
{% else %}
Other 404 message
{% endif %}
If your Symfony version is less than 2.1 you must use app.session.locale instead of app.request.locale
Nevertheless is a good practice to always create custom 404 and any other error page you need:
http://symfony.com/doc/current/cookbook/controller/error_pages.html
The most powerfull way is using this method:
Replace the default exception controller twig.controller.exception:showAction with your own controller and handle it however you want (see exception_controller in the Twig reference). The default exception controller is registered as a service - the actual class is Symfony\Bundle\TwigBundle\Controller\ExceptionController.
This way you can even have different templates for each country.
Kind regards.

How to pass an array from Symfony 2 controller to a TWIG template ?

I can`t pass an array from a symfony 2 controller to a TWIG template. I use this code in the controller:
$searchTerms['color'] = "Red";
return $this->render('TestBundle::search.html.twig',
array(
"searchTerms" => $searchTerms));
In the twig template, I am trying to access the variable like this:
{{ searchTerms['color'] }}
{{ searchTerms.color }}
Both output nothing, empty string, so it seems like array comes to template but its elements are empty.
What`s wrong?
Yes, this code works. The first thing to check is that your twig code is in the correct page (TestBundle::search.html.twig). This might sound silly but that happens sometimes...
If this is all good, I suggest that you try to debug within your template. Debugging is the most important thing. You will always have this kind of problem while programming, especially when you try something new. The better you are at debugging your code, the better you are as a programmer because there is no way you can get everything right the first time.
So, how can you debug?
To debug within your twig template, you can use the debug extension of twig. To activate the debug option, you will have to do a quick change in your config file. You can also read this thread if your lost.
You can debug any variable within your template like this:
<pre>
{% debug searchTerms %}
</pre>
This way, you can easily debug your variable and test what your problem is:
{% debug searchTerms['color'] %}
If you want to debug things quickly, I highly recommend that you use the LadyBugBundle. It is an awesome tool that will allow you to do something like that:
In your controller:
ladybug_dump($searchTerms);
In your TWIG template:
{{ searchTerms|ladybug_dump }}
Not that different from a classic var_dump option, but if you have long arrays or objects, ladybug will impress you. More importantly, in a controller, you will often have the need to stop the code at a certain point to avoid the page to load after your debug statement, this is fairly easy with ladybug:
ladybug_dump_die($searchTerms);
You can even ask ladybug to load the "debugged" variable into Symfony profiler with this simple statement.
$this->get('ladybug')->log($searchTerms);
You have now direct access of the variable from a tab of the Symfony2 profiler.
Ladybug can do a lot more, but for this, the doc is really good.
I think you must change template like this:
{% for item in searchTerms %}
{{ item.color }}<br/>
{% endfor %}
See official documentation: Creating and using Templates->embedding-controllers

How to get part of the page from other controller

My site I have some content can be voted (+/-). It is working fine now, when all content has its own voter.
Now I'm looking for a way to create a single voting bundle with a entity(votedModel,votedId, user, vote).
Basically the bundle is ready. My problem is how to use it. I'd like to be able to do something like:
class ... extends Controller {
function showAction(Request $request,$id) {
...
$voter=new Voter('myCOntentType',$id,$userid);
...
return $this->render('...', array('voter'=>$voter->getVoter(),...))
}
}
getVoter() would create the voter view.
but I'm stacked how exactly start. I tried to call for the other controller in this manner, but can't create the voter form.
It worked with $voter=$this->forward('VoterbundleNewAction', array('id=>$id,'user'=>$user)->getContent();But this wasn't I had in mind.
I think my approach is all wrong and I may need to do this as service. I cant find my way around.
You can use include or render in your twig template to get other templates' output. So you could create a template (say, voter.html.twig) that contains the HTML for your voting system, and in the Twig, in any place where you need a voter, you could use:
{% include "AcmeVoterBundle:Voter:voter.html.twig" %}
or
{% render "AcmeVoterBundle:Voter:voter" with {"item": item} %}
In the first example, you simply include another template (see also: http://symfony.com/doc/current/book/templating.html#including-other-templates), in the latter situation you actually execute another action method of a controller and the output of that is put into your current template (see also: http://symfony.com/doc/current/book/templating.html#embedding-controllers)

Categories