John Kary

This post was published when Symfony Standard Edition 2.3 was the latest stable release, and may be outdated for later Symfony versions.

Have you explored all of the Console commands that ship with the Symfony Standard Edition? The long list of tasks after entering the php app/console command might feel a bit overwhelming at first, but the more you use Symfony, the more comfortable you'll feel and the more likely you will have memorized a few common commands.

But there are a few commands that you don't hear much about that are very useful during every day development, but only garnish a quick blurb in the official documentation.

I spend most of my working day developing web applications where the frontend JavaScript application is fed data by an API built on the Symfony2 framework. What follows are some of the protips I've devised to help me work more efficiently and some of the non-obvious Symfony commands I use on a daily basis. I hope they help you develop faster and more efficiently!

  1. Alias your most common Symfony commands
    1. Alias the Symfony Console itself
    2. Alias the cache:clear command
    3. Alias the command to run your test suite
    4. Find other common commands you can alias
  2. Finding a specific service id or a service's class
  3. Finding a specific container parameter
  4. Finding a specific route name or URI
  5. Show all info about a specific route by its name
  6. Find which route matches a given URI
  7. Query your database from the CLI
    1. DQL queries
    2. SQL queries

1. Alias your most common Symfony commands

There are 3 commands I use so often I have short bash aliases setup for each:

Alias the Symfony Console itself

Developing with Symfony2, you will type php app/console many, many times. Having a faster way to type this is an instant productivity boost.

Add the following line to your .bash_profile file in your home directory to take your first step towards Symfony console mastery:

alias sf='php app/console'

Now reload your .bash_profile within you current shell session with the command source ~/.bash_profile and you can now access the Symfony console by typing sf in all places you would type php app/console.

Try using your new powers and ensure they're working properly:

$ sf
Symfony version 2.3.7 - app/dev/debug

Usage: [options] command [arguments]

Options: --help -h Display this help message. --quiet -q Do not output any message. ...

Alias the cache:clear command

You will clear the Symfony cache relatively often, so it deserves its own shell alias. As many will tell you, step 1 of troubleshooting Symfony issues is first clearing your cache!

alias sfcc="php app/console cache:clear"

The command sfcc will now clear your "dev" environment cache. The --env=dev option is implied for all Symfony commands unless otherwise specified, but you can easily specify any other environment too:

$ sfcc --env=test

Alias the command to run your test suite

You should be running your test suite often during development. The full command to run the Symfony test suite using PHPUnit is a bit long:

$ bin/phpunit -c app

Not too bad, but again, given how often you will be running this command, it deserves its own alias. (If you don't use PHPUnit, modify the alias to use whatever your test runner requires):

alias sft='bin/phpunit -c app'

Quickly reload your .bash_profile again via source ~/.bash_profile and you can now execute your test suite by typing sft:

$ sft
PHPUnit 3.7.28 by Sebastian Bergmann.

Configuration read from /path/to/your/project/app/phpunit.xml.dist

............................................................... 63 / 120 ( 52%) .........................................................

Time: 312 ms, Memory: 5.75Mb

OK (120 tests, 236 assertions)

With your new-found powers you can now quickly do things like only run tests within a specific directory:

$ sft src/Acme/DemoBundle/

Or run a specific test by its name:

$ sft --filter=testUserStartsAsActive

Or quickly generate code coverage:

$ sft --coverage-html=coverage

Of course you could always run these exact commands without the alias, but the key is allocating less mental energy to mundane things like typing long commands for commonly used commands.

Find other common commands you can alias

You could try noticing your habits and alias other common commands, but why not let your console history just tell you?

$ history | grep 'php app/console'
[... your most recent history containing 'php app/console' will appear here ...]

2. Finding a specific service id or a service's class

Often you will need to see if your newly defined service is wired up how you intend it to be. The following command will display all defined services in the Symfony2 service container:

$ sf container:debug

If you have an idea of what you're looking for, pipe this command's output to grep <you search string here>. For example, let's list all the services containing the word "doctrine":

$ sf container:debug | grep doctrine
database_connection                                    n/a       alias for doctrine.dbal.default_connection
doctrine                                               container Doctrine\Bundle\DoctrineBundle\Registry
doctrine.dbal.connection_factory                       container Doctrine\Bundle\DoctrineBundle\ConnectionFactory
doctrine.dbal.default_connection                       container stdClass
doctrine.orm.default_entity_manager                    container EntityManager5292d7ee8f526_546a8d27f194334ee012bfe64f629947b07e4919__CG__\Doctrine\ORM\EntityManager
doctrine.orm.default_manager_configurator              container Doctrine\Bundle\DoctrineBundle\ManagerConfigurator
doctrine.orm.entity_manager                            n/a       alias for doctrine.orm.default_entity_manager
doctrine.orm.validator.unique                          container Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator
doctrine.orm.validator_initializer                     container Symfony\Bridge\Doctrine\Validator\DoctrineInitializer
form.type_guesser.doctrine                             container Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser
monolog.logger.doctrine                                container Symfony\Bridge\Monolog\Logger
sensio_framework_extra.converter.doctrine.orm          container Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter

This command also accepts a service id as its first argument and will output even more information about that how it is wired up. Let's look at the service with id "twig.loader":

$ sf container:debug twig.loader
[container] Information for service twig.loader

Service Id twig.loader Class Symfony\Bundle\TwigBundle\Loader\FilesystemLoader Tags - twig.loader () Scope container Public yes Synthetic no Required File -

(I wish this output contained things like what other services/parameters are wired into it, what factory methods are run when instantiated, etc. If you know how to find this output from the Console, please comment below.)

3. Finding a specific container parameter

While sf container:debug outputs a list of services, calling this command with the additional option --parameters will dump a list of all service container parameters and their values. This is useful to ensure your config or bundle is overriding the intended parameter or just to see what all parameters are available without digging into a Bundle's Extension or Configuration files:

$ sf container:debug --parameters

Using this command's output with grep, like in the previous example, is also your friend.

You can also use the similar option --parameter="..." (notice no "s" in "parameter") to find the value for a specific parameter. Let's find exactly which class will be used for Doctrine's EntityManager by finding the value for the "doctrine.orm.entity_manager.class" parameter:

$ sf container:debug --parameter="doctrine.orm.entity_manager.class"
Doctrine\ORM\EntityManager

4. Finding a specific route name or URI

Like finding values in the Service Container, a similar command exists to search Symfony's Router for route names and URI paths:

$ sf router:debug
[router] Current routes
Name                Method Scheme Host Path
index               ANY    ANY    ANY  /
users_list          ANY    ANY    ANY  /users/
users_new           ANY    ANY    ANY  /users/new
users_edit          ANY    ANY    ANY  /users/{id}

I often use this command as a dummy-check that my Controller @Route annotations are wired properly and that they have the correct @Method annotation values.

5. Show all info about a specific route by its name

The first optional argument to router:debug is the route name. This shows all details for the route named "users_list":

$ sf router:debug users_list
[router] Route "users_list"
Name         users_list
Path         /users/
Host         ANY
Scheme       ANY
Method       ANY
Class        Symfony\Component\Routing\Route
Defaults     _controller: Acme\DemoBundle\Controller\UsersController::indexAction
Requirements NO CUSTOM
Options      compiler_class: Symfony\Component\Routing\RouteCompiler
Path-Regex   #^/users/$#s

6. Find which route matches a given URI

You might know the URI path but not the route name. The router:match command works like router:debug but does the reverse operation by accepting a URI argument instead of the route name.

The following example shows which route matches the URI "/users":

$ sf router:match /users
Route "users_list" matches

[router] Route "users_list" Name users_list Path /users/ Host ANY Scheme ANY Method ANY Class Symfony\Component\Routing\Route Defaults _controller: Acme\DemoBundle\Controller\UsersController::indexAction Requirements NO CUSTOM Options compiler_class: Symfony\Component\Routing\RouteCompiler Path-Regex #^/users/$#s

7. Query your database from the CLI

It can be a hassle to write up a functional test or other code that executes DQL or SQL you are tweaking for a new query or troubleshooting an existing query. Thankfully Doctrine offers two commands that let you run queries straight from the command-line.

DQL queries

You can query your database using raw DQL right from the command-line using the command doctrine:query:dql. Just pass in the full DQL you want to execute:

$ sf doctrine:query:dql "SELECT u.firstName, u.lastName, u.lastLogin FROM AcmeDemoBundle:User u" --hydrate=array

array (size=1) 0 => array (size=3) 'firstName' => string 'John' (length=4) 'lastName' => string 'Smith' (length=5) 'lastLogin' => object(stdClass)[325] public 'CLASS' => string 'DateTime' (length=8) public 'date' => string '2013-11-26T00:00:00-06:00' (length=25) public 'timezone' => string 'America/Chicago' (length=15)

Appending the option --hydrate=array like in the previous example is also useful if your selected entities have other entity relationships, where the resulting var_dump() of object data creates a lot of additional clutter. Hydrating as an array is a bit cleaner to look at if you're only interested in the data and not the underlying object structure.

SQL queries

You can also directly query your database using raw SQL without connecting through the mysql binary or a GUI application. Like querying for DQL, the connection data from parameters.yml or config.yml is used, so there's no hassle with passing the right credentials with each query:

$ php app/console doctrine:query:sql "SELECT * from users"

array (size=1) 0 => array (size=5) 'id' => string '5' (length=1) 'firstName' => string 'John' (length=4) 'lastName' => string 'Smith' (length=5) 'logins' => null 'lastLogin' => string '2013-11-26' (length=10)

Did I miss anything?

What do you think? Did you learn something that can make you more productive? Are there other productivity wins you wish I had included? I'd love to hear your feedback in the comments section below!

comments powered by Disqus