Symfony2 aided by PhpStorm

An earlier post here did not help me much whenever I went back and tried to debug a bit more on a project at hand.

The problems I had:

  • I had set it up my phpstorm with xdebug to debug projects on symfony2, however I had not tried in a while so I forgot how I did it in the first place.
  • My debugger had problems recognizing the .cache extension that the bootstrap cache files had in Symfony2. Because of this I could not enter with breakpoints into any of the files of my project.
  • I did not understand the process of debugging an app in Symfony2 well so I was scared about something may break or that it would be too complex.
  • I thought it was faster to use var_dump or print_r commands to output variables to the console to check my results.

So firstly, in order to get back at speed with phpstorm debugging I just fired up the listening connections icon, it is a phone icon and then I created or recreated some debug configurations. Set a server to my project local domain and all set. Then I was at least getting the connection right and Ctrl+F9 and Ctrl+F8 were my friends.

Secondly, I was told by phpstorm support person that I had to associate the cache file extensions as text files. This I did by going to Settings > File Type under IDE settings and then assign or reassign the extension *.cache which if already assigned asked me to forcefully reassign to new association. This solved the problem of stepping into beyon the bootstrap cache files.

Here I show a valid configuration for my xdebug.ini that sets the configuration for phpstorm xdebug communication.

$cat /etc/php5/cli/conf.d/xdebug.ini zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so
xdebug.remote_host=127.0.0.1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req

A more involved version of the configuration file can be found here as shared by phpstorm support person:

root@mvubdevel:~# cat /etc/php5/fpm/conf.d/xdebug.ini
zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.idekey=default
xdebug.remote_host=127.0.0.1
xdebug.remote_autostart=0
xdebug.var_display_max_children=512
xdebug.var_display_max_data=32000
xdebug.var_display_max_depth=8
xdebug.remote_log=/tmp/xdbg.log
;xdebug.profiler_enable=1
;xdebug.profiler_output_dir=/tmp
;xdebug.profiler_output_name=cachegrind.out.%u

Following I am trying to do a snap shot of each of the steps that an Symfony2 app undergoes:

Symfony2 starts on the front controller and directly loads the UniversalClassLoader. This is in our development version which does not use the bootstrap cache file. Here it loads it so that the autoload file in our app/ folder is called every time. It also loades the Kernel.

require_once __DIR__.'/../vendor/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
require_once __DIR__.'/../app/autoload.php';
require_once __DIR__.'/../app/AppKernel.php';

When creating a kernel class with $kernel = new AppKernel('dev', true); Symfony2 loads basic startup variables and timing with the constructor of the kernel class. Then handles responsibility over to the handle methods of the class $kernel->handle(Request::createFromGlobals())->send();.

Symfony2 right away starts loading the classes needed to execute the code of the application by pulling them with the loadClass method of DebugUniversalClassLoader.php.

Meanwhile there is a Request object which is initialized by the createFromGlobals() method. This basically is the building block for HTTP request protocol.

After the above steps take place the handling of the request is fired up after the Kernel has been set as booted.

A Response object has been created by all the grinding associated with the steps above. Now it is time to call the method send from the Response object.

The job has been accomplished, and now it is time to remove all used material.

Symfony2 proceeds to the destruction of serializable session class. For his it has a destruct magic method and before it does destructs the class it saves the session if the session started parameter is set. Else it will just destruct and not persist anything.

public function __destruct()
    {
        if (true === $this->started) {
            $this->save();
        }
    }

The Monolog package also creates an object that implements an Abstract Handler that follows destruction of the session object above. The Monolog object then calls its destruct method and basically calls a method which is empty.
public function __destruct()

    {
        $this->close();
    }

For some reason the monolog handler is called two or three times.

After I inserted several break points into my controller, right before it gets redirected then I stepped through the code and found that some variables were not properly defined.

Some more information can be found in the cookbook entry that I was pointed to here and also here.

Leave a Reply

Your email address will not be published. Required fields are marked *