Skip to content

Updated the profiler matchers article #5593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 33 additions & 26 deletions cookbook/profiler/matchers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
How to Use Matchers to Enable the Profiler Conditionally
========================================================

By default, the profiler is only activated in the development environment. But
it's imaginable that a developer may want to see the profiler even in
production. Another situation may be that you want to show the profiler only
when an admin has logged in. You can enable the profiler in these situations
by using matchers.
The Symfony profiler is only activated in the development environment to not hurt
your application performance. However, sometimes it may be useful to conditionally
enable the profiler in the production environment to assist you in hard to debug
issues. This behavior is implemented with the **Request Matchers**.

Using the built-in Matcher
--------------------------

Symfony provides a
A Request Matcher is a class that checks whether a given ``Request`` instance
matches a set of conditions. Symfony provides a
:class:`built-in matcher <Symfony\\Component\\HttpFoundation\\RequestMatcher>`
which can match paths and IPs. For example, if you want to only show the
profiler when accessing the page with the ``168.0.0.1`` IP, then you can
use this configuration:
which matches paths and IPs. For example, if you want to only show the profiler
when accessing the page with the ``168.0.0.1`` IP, then you can use this
configuration:

.. configuration-block::

Expand Down Expand Up @@ -50,22 +50,24 @@ use this configuration:

You can also set a ``path`` option to define the path on which the profiler
should be enabled. For instance, setting it to ``^/admin/`` will enable the
profiler only for the ``/admin/`` URLs.
profiler only for the URLs which start with ``/admin/``.

Creating a custom Matcher
Creating a Custom Matcher
-------------------------

You can also create a custom matcher. This is a service that checks whether
the profiler should be enabled or not. To create that service, create a class
Leveraging the concept of Request Matchers you can define a custom matcher to
enable the profiler conditionally in your application. To do so, create a class
which implements
:class:`Symfony\\Component\\HttpFoundation\\RequestMatcherInterface`. This
interface requires one method:
:method:`Symfony\\Component\\HttpFoundation\\RequestMatcherInterface::matches`.
This method returns false to disable the profiler and true to enable the
profiler.
This method returns ``false`` when the request doesn't match the conditions and
``true`` otherwise. Therefore, the custom matcher must return ``false`` to
disable the profiler and ``true`` to enable it.

To enable the profiler when a ``ROLE_SUPER_ADMIN`` is logged in, you can use
something like::
Suppose that the profiler must be enabled whenever a user with a
``ROLE_SUPER_ADMIN`` is logged in. This is the only code needed for that custom
matcher::

// src/AppBundle/Profiler/SuperAdminMatcher.php
namespace AppBundle\Profiler;
Expand All @@ -89,24 +91,26 @@ something like::
}
}

Then, you need to configure the service:
Then, configure a new service and set it as ``private`` because the application
won't use it directly:

.. configuration-block::

.. code-block:: yaml

# app/config/services.yml
services:
app.profiler.matcher.super_admin:
app.super_admin_matcher:
class: AppBundle\Profiler\SuperAdminMatcher
arguments: ["@security.context"]
public: false

.. code-block:: xml

<!-- app/config/services.xml -->
<services>
<service id="app.profiler.matcher.super_admin"
class="AppBundle\Profiler\SuperAdminMatcher">
<service id="app.super_admin_matcher"
class="AppBundle\Profiler\SuperAdminMatcher" public="false">
<argument type="service" id="security.context" />
</services>

Expand All @@ -116,12 +120,15 @@ Then, you need to configure the service:
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

$container->setDefinition('app.profiler.matcher.super_admin', new Definition(
$definition = new Definition(
'AppBundle\Profiler\SuperAdminMatcher',
array(new Reference('security.context'))
);
$definition->setPublic(false);

Now the service is registered, the only thing left to do is configure the
$container->setDefinition('app.super_admin_matcher', $definition);

Once the service is registered, the only thing left to do is configure the
profiler to use this service as the matcher:

.. configuration-block::
Expand All @@ -133,15 +140,15 @@ profiler to use this service as the matcher:
# ...
profiler:
matcher:
service: app.profiler.matcher.super_admin
service: app.super_admin_matcher

.. code-block:: xml

<!-- app/config/config.xml -->
<framework:config>
<!-- ... -->
<framework:profiler
service="app.profiler.matcher.super_admin"
service="app.super_admin_matcher"
/>
</framework:config>

Expand All @@ -151,6 +158,6 @@ profiler to use this service as the matcher:
$container->loadFromExtension('framework', array(
// ...
'profiler' => array(
'service' => 'app.profiler.matcher.super_admin',
'service' => 'app.super_admin_matcher',
),
));