Using Plop usually involves 3 steps, detailed below.

TL;DR: simply read the section on Loading Plop’s classes then skip all the way down to the section on Logging some messages.

Loading Plop’s classes

The way to load Plop’s classes depends on the installation method selected:

  • For the PHAR installation method, add this snippet near the top of your main PHP file:


    (adjust the path with the name of the PHAR archive you downloaded)

  • For the Composer installation method, add this snippet instead near the top of your main PHP file:

  • For an installation from sources,


If you’re not interested in fine-tuning Plop, you may skip the rest of this page until you reach the part about Logging some messages.

Configuring Plop

There are 4 different types of objects that you can configure in Plop. Each one is described below.


A logger intercepts log messages for a given method, class, file or directory. This is decided at construction time based on the arguments passed to Plop::Logger::__construct.

Internally, Plop builds up a hierarchy of loggers like so:

root-level logger
    namespace-level logger
        class-level logger
            method/function-level logger

Log messages “bubble up”. That is, Plop first looks for a method or function-level logger to handle the message. If none can be found, it looks for a class-level logger (in case the message was emitted from a method). Then it looks for a namespace-level logger, then a logger for the parent’s namespace, etc. until it reaches the root-level logger, which always exists.

Whichever logger is found first will be the one to handle the message.


The root-level logger) comes pre-configured with a handler that logs messages to STDERR using some very basic formatting.

Several aspects of a logger can be configured, such as:

  • The logging level. Whenever a message is received whose level is lower than the logger’s logging level, the message is ignored, but no other logger will be called to handle the message (effectively preventing the message from bubbling further).
  • The record factory. This factory is used to create records of logging messages, intended to keep track of the message’s contextual information. This factory must implement the Plop::RecordFactoryInterface interface and is usually an instance of Plop::RecordFactory.
  • Filters.
  • Handlers.

Once a logger has been created and configured, you can tell Plop about it, using the following code snippet:

$logging = \Plop\Plop::getInstance();
$logging[] = $newlyCreatedLogger;

This will add the logger to the list of loggers already known to Plop. If a logger had already been registered in Plop with the same “identity” (ie. the same namespace, class and method names), it will automatically be replaced with the new one.

See also

Detailed API documentation on the interface implemented by loggers.
An abstract class that can be useful when implementing your own logger.
An abstract class that can be useful when implementing an indirect logger. An indirect logger is a logger which relies on another logger to work. Plop’s main class (Plop) is an example of such a logger.
The most common type of logger.
A logger that supports the PSR-3 \Psr\Log\LoggerInterface interface.


Filters are associated with either loggers or handlers through an object implementing Plop::FiltersCollectionInterface (usually an instance of Plop::FiltersCollection) and are used to restrict which messages will be handled. They are applied once the message has been turned into a log record and work by defining various criteria such a record must respect.

If a record respects all of the criteria given in the collection, the handlers associated with the logger are called in turn to do their work.


The “level” associated with a logger acts like a lightweight filter. In fact, the same effect could be obtained by defining a collection containing an instance of Plop::Filter::Level with the level desired.


Not all handlers make use of filters. Therefore, depending on the handlers used, it is possible that the filters will be ignored entirely.

To associate a new filter with a logger or handler, use the following code snippet:

$filters = $logger_or_handler->getFilters();
$filters[] = $newFilter;

Please note that this will not replace existing filters. Records will still have to pass the previous filters, but they will also have to pass the new filter before they can be handled.

See also

Detailed API documentation for the interface representing a collection of filters.
Detailed API documentation for the interface implemented by all filters. This page also references all the filters that can be used in a collection.


Handlers are associated with loggers through an object implementing Plop::HandlersCollectionInterface (usually an instance of Plop::HandlersCollection) and are used to define the treatment applied to log records.

Various types of handlers exist that can be used to log message to different locations such as the system’s event logger (syslog), a (rotated) file, a network socket, ...

Like with loggers, several aspects of a handler can be configured:

To associate a new handler with a logger, use the following code snippet:

$handlers = $logger->getHandlers();
$handlers[] = $newHandler;

Please note that this will not replace existing handlers. Also, both the previously defined handlers and the newly added one will be called when a log record must be handled.

See also

Detailed API documentation for the interface representing a collection of handlers.
An abstract class that can be useful when implementing a new handler.
Detailed API documentation for the interface implemented by all handlers. This page also references all the handlers that can be used in a collection.


Each handler has an associated formatter, which is used when a record needs formatting. A formatter defines how the final message will look like.

There are a few things about a formatter that you can configure:

  • The main format. This string serves as a pattern for the final message.

    When using an instance of Plop::Formatter with default settings as the formatter, it may contain Python-like string formats using the syntax for dictionaries.

    That is, it may contain something like the following:

    [%(asctime)s] %(levelname)s - %(message)s

    The default format in that case is defined in Plop::Formatter::DEFAULT_FORMAT.

    Several pre-defined formats exist that depend on the particular implementation used to represent records. For example, Plop::Record closely follows the formats defined by Python’s logging module whenever they are applicable.

  • The format for dates and times.

    When using an instance of Plop::Formatter as the formatter, it uses the formatting options from PHP’s date() function. Also, the default format for dates and times is then defined in Plop::Formatter::DEFAULT_DATE_FORMAT.

  • The current timezone as a DateTimeZone object. This information is used when formatting dates and times for log records that were created in a timezone that does not match the local timezone.

To associate a new formatter with a handler, use the following code snippet:


Please note that this will replace any formatter previously in place.

See also

Detailed API documentation for the interface implemented by all formatters.
The most common implementation of formatters.
The most common implementation for log records.
PHP’s predefined constants to represent several popular types of date/time formatting.
List of timezone identifiers supported by PHP.

Logging some messages

Logging messages with Plop usually only involves the following sequence:

// First, grab an instance of Plop.
// Plop uses a singleton pattern, so the same instance will be returned
// every time you use this method, no matter where you're calling it from.
$logging = \Plop\Plop::getInstance();

// Now, send a log.
// Various log levels are available by default:
// debug, info, notice, warning, error, critical, alert & emergency.
// There's a method named after each log level's name.
$logging->debug('Hello world');

Log messages may contain variables, which will be replaced with their actual value when the logging method is called. This is useful in a lot of situations. For example, you can use it to apply i18n methods to the messages:

$logging = \Plop\Plop::getInstance();
    _('Sorry %(nick)s, now is not the time for that!'),
        'nick' => 'Ash',

Table Of Contents

Previous topic


Next topic