The Sentry PHP SDK provides support for PHP 7.1 or later.

Integrating the SDK

Sentry captures data by using an SDK within your application’s runtime. These are platform-specific and allow Sentry to have a deep understanding of how your application works.

To install the PHP SDK, you need to be using Composer in your project. For more details about Composer, see the Composer documentation.

composer require sentry/sdk

Connecting the SDK to Sentry

After you’ve completed setting up a project in Sentry, Sentry will give you a value which we call a DSN or Data Source Name. It looks a lot like a standard URL, but it’s just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier.

To capture all errors, even the one during the startup of your application, you should initialize the Sentry PHP SDK as soon as possible.

Sentry\init(['dsn' => '___PUBLIC_DSN___' ]);

Verifying Your Setup

Great! Now that you’ve completed setting up the SDK, maybe you want to quickly test out how Sentry works. You can trigger a PHP exception by throwing one in your application:

throw new Exception("My first Sentry error!");

Capturing Errors

In PHP you can either capture a caught exception or capture the last error with captureLastError.

try {
} catch (\Throwable $exception) {

// OR



A release is a version of your code that you deploy to an environment. When you give Sentry information about your releases, you unlock many new features:

  • Determine the issue and regressions introduced in a new release
  • Predict which commit caused an issue and who is likely responsible
  • Resolve issues by including the issue number in your commit message
  • Receive email notifications when your code gets deployed

After configuring your SDK, setting up releases is a 2-step process:

  1. Create Release and Associate Commits
  2. Tell Sentry When You Deploy a Release

For more information, see Releases Are Better With Commits.

Finally, configure the SDK to send release information:

  'dsn' => '___PUBLIC_DSN___',
  'release' => 'your release name'


Sentry supports additional context with events. Often this context is shared among any issue captured in its lifecycle, and includes the following components:

Structured Contexts

Structured contexts are typically set automatically.


Information about the current actor.


Key/value pairs which generate breakdown charts and search filters.


An event’s severity.


A value used for grouping events into issues.

Unstructured Extra Data

Arbitrary unstructured data which the Sentry SDK stores with an event sample.

Extra Context

In addition to the structured context that Sentry understands, you can send arbitrary key/value pairs of data which the Sentry SDK will store alongside the event. These are not indexed, and the Sentry SDK uses them to add additional information about what might be happening.

Sentry\configureScope(function (Sentry\State\Scope $scope): void {
  $scope->setExtra('character_name', 'Mighty Fighter');

Capturing the User

Sending users to Sentry will unlock many features, primarily the ability to drill down into the number of users affecting an issue, as well as to get a broader sense about the quality of the application.

Sentry\configureScope(function (Sentry\State\Scope $scope): void {
  $scope->setUser(['email' => '']);

Users consist of a few critical pieces of information which are used to construct a unique identity in Sentry. Each of these is optional, but one must be present for the Sentry SDK to capture the user:


Your internal identifier for the user.


The user’s username. Generally used as a better label than the internal ID.


An alternative, or addition, to a username. Sentry is aware of email addresses and can show things like Gravatars, unlock messaging capabilities, and more.


The IP address of the user. If the user is unauthenticated, providing the IP address will suggest that this is unique to that IP. If available, we will attempt to pull this from the HTTP request data.

Additionally, you can provide arbitrary key/value pairs beyond the reserved names, and the Sentry SDK will store those with the user.

Tagging Events

Tags are key/value pairs assigned to events that can be used for breaking down issues or quick access to finding related events.

Most SDKs generally support configuring tags by configuring the scope:

Sentry\configureScope(function (Sentry\State\Scope $scope): void {
  $scope->setTag('page_locale', 'de-at');

Several common uses for tags include:

  • The hostname of the server
  • The version of your platform (For example, iOS 5.0)
  • The user’s language

Once you’ve started sending tagged data, you’ll see it show up in a few places:

  • The filters within the sidebar on the project stream page.
  • Summarized within an event on the sidebar.
  • The tags page on an aggregated event.

We’ll automatically index all tags for an event, as well as the frequency and the last time the Sentry SDK has seen a value. Even more so, we keep track of the number of distinct tags and can assist you in determining hotspots for various issues.

Setting the Level

You can set the severity of an event to one of five values: fatal, error, warning, info, and debug. error is the default, fatal is the most severe and debug is the least severe.

Sentry\configureScope(function (Sentry\State\Scope $scope): void {

Setting the Fingerprint

Sentry uses one or more “fingerprints” to decide how to group errors into issues.

For some very advanced use cases, you can override the Sentry default grouping using the fingerprint attribute. In supported SDKs, this attribute can be passed with the event information and should be an array of strings.

If you wish to append information, thus making the grouping slightly less aggressive, you can do that as well by adding the special string `` as one of the items.

For more information, see Aggregate Errors with Custom Fingerprints.

Advanced Usage

Sentry will automatically record specific events, such as changes to the URL and XHR requests to provide context to an error.

You can manually add breadcrumbs on other events or disable breadcrumbs.

Sentry\addBreadcrumb(new Sentry\Breadcrumb(
  'foo bar'

For more information, see:

Filter Events & Custom Logic

Sentry exposes a beforeSend callback which can be used to filter out information or add additional context to the event object.

  'dsn' => '___PUBLIC_DSN___',
  'before_send' => function (Sentry\Event $event): ?Event {
    return $event;

For more information, see:


Integrations extend the functionality of the SDK for some common frameworks and libraries. Similar to plugins, they extend the functionality of the Sentry SDK.
Integrations are configured by a call to init() method.

Web Frameworks

Default Integrations

Default integrations are integrations enabled by default that integrate into the standard library or the interpreter itself. They are documented so you can see what they do and that they can be disabled if they cause issues. To disable system integrations set default_integrations => false when calling init().

For more information, see full documentation on Default Integrations.

PHP Specific Options

PHP provides some additional options, all options can be passed into init().


This option enables capturing errors which were silenced using the @ operator in your source code. Defaults to false.


This option sets the number of lines of code context to capture. If null is set as the value, no source code lines will be added to each stack trace frame. By default this option is set to 3.


If this option is enabled, gzip compression will be enabled. Default is true.


This option accepts an int bitmask like the native PHP function error_reporting. This value is used in the default ErrorListenerIntegration to filter out errors: the default value will send all errors (same as setting E_ALL); if you want to exclude some types of errors, you just need to apply the right bitmask.

For example, if you want to get all errors but exclude notices and deprecations, the right bitmask to apply is E_ALL & ~E_NOTICE & ~E_DEPRECATED.


This option configures the list of paths to exclude from the app_path detection.


Sometimes you may want to skip capturing certain exceptions. This option sets the FQCN of the classes of the exceptions that you don’t want to capture. The check is done using the instanceof operator against each item of the array and if at least one of them passes the event will be discarded.

Note that this behavior applies to the captureException function/method, which is also used in the automatic capture of errors; it’s not applied to the captureEvent function/method instead, that could be used as a manual override.


This option sets the list of prefixes which should be stripped from the filenames to create relative paths.


The root of the project source code. As Sentry is able to distinguish project files from third-party ones (e.g. vendors), this option can be configured to mark the directory containing all the source code of the application.

For example, assuming that the directory structure shown below exists, marking the project root as project-folder/src/ means that every file inside that directory that is part of a stack trace frame will be marked as “application code”.

    ├── vendor/
        ├── foo/
    ├── src/
        ├── bar/ <-- these are going to be marked as application files


The number of attempts that should be made to send an event before erroring and dropping it from the queue. By default this option is set to 6.


This option represents the size limit in bytes beyond which the body of the request is not captured. The default value is medium. Possible values are none = never send body, small, medium, always = always send the body, no matter how large it is. The values are chosen like this on purpose since the SDK internally can define what the exact limits are.


Sentry PHP is not tied to any specific library that sends HTTP messages. Instead, it uses Httplug to let users choose whichever PSR-7 implementation and HTTP client they want to use.

We recommend that you use the sentry/sdk meta-package which provides our recommend HTTP client.

If you want to use a different HTTP client just install sentry/sentry with the clients you prefer:

composer require sentry/sentry:2.4.1 php-http/curl-client guzzlehttp/psr7

This will install the library itself along with an HTTP client adapter that uses cURL as the transport method (provided by Httplug and a PSR-7 implementation (provided by Guzzle). You do not have to use those packages if you do not want to. The SDK does not care about which transport method you want to use because it’s an implementation detail of your application. You may use any package that provides php-http/async-client-implementation and http-message-implementation.

If you want to use Guzzle as an underlying HTTP client, you just need to run the following command to install the adapter and Guzzle itself:

composer require php-http/guzzle6-adapter

Transport Classes

Transports are the classes in Sentry PHP that are responsible for communicating with a service in order to deliver an event. There are several types of transports available out-of-the-box, all of which implement the TransportInterface interface;

  • The NullTransport which is used in case you do not define a DSN in the options. It will not send events.
  • The HttpTransport which is the default and will be used when the server is set in the client configuration.
  • The SpoolTransport which can be used to defer the sending of events (e.g. by putting them into a queue).

The examples below pretty much replace the init() call.
Please also keep in mind that once a Client is initialized with a Transport it cannot be changed.


Although not so common there could be cases in which you don’t want to send events at all. The NullTransport transport does this: it simply ignores the events, but report them as sent.

use Sentry\ClientBuilder;
use Sentry\Transport\NullTransport;
use Sentry\State\Hub;
use Sentry\Transport\TransportFactoryInterface;

$transportFactory = new class implements TransportFactoryInterface {

    public function create(\Sentry\Options $options): \Sentry\Transport\TransportInterface
        return new NullTransport();

$builder = ClientBuilder::create(['dsn' => '___PUBLIC_DSN___']);


The HttpTransport sends events over the HTTP protocol using Httplug. The best adapter available is automatically selected when creating a client instance through the client builder, but you can override it using the appropriate methods.

use Http\Discovery\HttpAsyncClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\StreamFactoryDiscovery;
use Http\Discovery\UriFactoryDiscovery;
use Http\Message\ResponseFactory;
use Http\Message\UriFactory;
use Sentry\ClientBuilder;
use Sentry\HttpClient\HttpClientFactory;
use Sentry\HttpClient\HttpClientFactoryInterface;
use Sentry\Transport\HttpTransport;
use Sentry\State\Hub;
use Sentry\Transport\TransportFactoryInterface;

$httpClientFactory = new HttpClientFactory(

$transportFactory = new class($httpClientFactory) implements TransportFactoryInterface  {
     * @var HttpClientFactoryInterface
    private $clientFactory;

    public function __construct(HttpClientFactoryInterface $clientFactory)
        $this->clientFactory = $clientFactory;

    public function create(\Sentry\Options $options): \Sentry\Transport\TransportInterface
        return new HttpTransport($options, $this->clientFactory->create($options), MessageFactoryDiscovery::find());

$builder = ClientBuilder::create(['dsn' => '___PUBLIC_DSN___']);


The default behavior is to send events immediately. You may, however, want to avoid waiting for the communication to the Sentry server that could be slow or unreliable. Avoid this by choosing the SpoolTransport which stores the events in a queue so that another process can read it and take care of sending them. Currently only spooling to memory is supported.

use Sentry\ClientBuilder;
use Sentry\Transport\SpoolTransport;
use Sentry\Transport\HttpTransport;
use Sentry\State\Hub;

$options = ['dsn' => '___PUBLIC_DSN___'];

$httpTransport = new HttpTransport($options, HttpAsyncClientDiscovery::find(), MessageFactoryDiscovery::find());

$spool = new MemorySpool();

$transportFactory = new class implements TransportFactoryInterface {
    public function create(\Sentry\Options $options): \Sentry\Transport\TransportInterface
        return new SpoolTransport($spool);

$builder = ClientBuilder::create($options);


// When the spool queue is flushed the events are sent using the transport
// passed as parameter of the flushQueue method.