Spiral does not come with built-in tools for variable dumping, but fear not! There are third-party packages available to help us out.
With the spiral/dumper
package, developers can effortlessly inspect and analyze variable values during the development
process. This package is an invaluable asset for debugging and troubleshooting in both web and CLI applications.
The component acts as a wrapper over the symfony/var-dumper library. It allows you to send dumps directly to the browser within HTTP workers or to the STDERR output in other environments.
By default, the spiral/dumper
package is already included in the spiral/app
skeleton. However, if you're using a
different skeleton, you can easily install the package using the following command:
composer require spiral/dumper
To dump variables, simply utilize the helper function dump()
provided by the package.
dump($variable);
Alternatively, you can opt for the symfony/var-dumper
package as a debugging solution. This package offers a straightforward server that collects all the dumped data. You can
start the server using a command, and it will listen for data sent by the dump()
function.
To install the package, execute the following command:
composer require symfony/var-dumper
To start the server, run the following command:
./vendor/bin/var-dump-server
To use this feature, you also need to define the VAR_DUMPER_FORMAT
environment variable in your .env
file
as follows:
VAR_DUMPER_FORMAT=server
By doing this, you instruct the package to send the dumped data to the server instead of displaying it in the output.
Debugging the Spiral application is as feasible as debugging any other classic PHP application when utilizing the xDebug extension.
Ad first, you need to configure your IDE to work with xDebug.
See more
Read more about the IDE configuration in the official documentation.
It is more convenient to start RoadRunner with xDebug enabled only when it's needed. Add the following env variables to
.rr.yaml
to properly configure xDebug:
env:
PHP_IDE_CONFIG: serverName=application.loc
XDEBUG_CONFIG: remote_host=localhost max_nesting_level=250 remote_enable=1 remote_connect_back=0 var_display_max_depth=5 idekey='PHPSTORM'
Note
Alter values according to your environment.
To enable xDebug, run the application server with -o
(overwrite flag) for the required service:
./rr serve -o "server.command=php -d zend_extension=xdebug app.php"
To alter workers config in docker, use the following or similar config for your container:
version: "2"
services:
...
app:
...
command:
- /usr/local/bin/rr
- serve
- -o
- server.command=php -d zend_extension=xdebug.so app.php
environment:
PHP_IDE_CONFIG: serverName=application.loc
XDEBUG_CONFIG: remote_host=host.docker.internal max_nesting_level=250 remote_enable=1 remote_connect_back=0 var_display_max_depth=5 idekey='PHPSTORM'
Buggregator is a beautiful, lightweight standalone server built on Spiral Framework, NuxtJs and RoadRunner underhood. It helps debugging mostly PHP applications without extra packages.
It supports collecting and displaying data from the following tools and services:
You can run Buggregator via docker from the Github Packages
docker run --pull always ghcr.io/buggregator/server:dev
-p 8000:8000
-p 1025:1025
-p 9912:9912
-p 9913:9913
docker run --pull always ghcr.io/buggregator/server:latest
-p 8000:8000
-p 1025:1025
-p 9912:9912
-p 9913:9913
version: "2"
services:
# ...
buggregator:
image: ghcr.io/buggregator/server:dev
ports:
- 8000:8000
- 1025:1025
- 9912:9912
- 9913:9913
That's it. Now you open http://127.0.0.1:8000 url in your browser and collect dumps from your application.
XHProf is a tool that helps you figure out how your PHP code is running and where it might be slow. It keeps track of how many times different parts of your code get called, and how long they take. It also can help you figure out how much memory your code is using. Spiral has a spiral/profiler package that makes it easy to use XHProf in your PHP application. It provides a simple and convenient way to use the XHProf profiler during the development or profiling period, so you can quickly identify and optimize performance bottlenecks in your code.
To begin, you need to install the Xhprof extension. One way to do this is by using the PECL package.
pear channel-update pear.php.netpecl install xhprof
Next, install the profiler package:
Once the package is installed, add the bootloader from the package to your application.
protected const LOAD = [
// ...
\Spiral\Profiler\ProfilerBootloader::class,
// ...
];
Use the following environment variables to configure the profiler to send data to the Buggregator server:
PROFILER_ENDPOINT=http://127.0.0.1:8000/api/profiler/store
PROFILER_APP_NAME=My super app
There are two ways to use profiler:
Interceptor will be useful if you want to profile some specific part of your application which supports using interceptors.
See more
Read more about interceptors in the Framework — Interceptors section.
To use the profiler as an interceptor, you just need to register Spiral\Profiler\ProfilerInterceptor
class.
Here is an example of how to use the profiler as an interceptor in the http layer:
namespace App\Application\Bootloader;
use Spiral\Bootloader\DomainBootloader;
use Spiral\Core\CoreInterface;
class AppBootloader extends DomainBootloader
{
protected const SINGLETONS = [
CoreInterface::class => [self::class, 'domainCore']
];
protected const INTERCEPTORS = [
\Spiral\Profiler\ProfilerInterceptor::class
];
}
Middleware will be useful if you want to profile all requests to your application. To use profiler as a middleware you need to add it to your router.
See more
Read more about middleware in the HTTP — Routing section.
namespace App\Application\Bootloader;
use Spiral\Bootloader\Http\RoutesBootloader as BaseRoutesBootloader;
use Spiral\Profiler\ProfilerMiddleware;
final class RoutesBootloader extends BaseRoutesBootloader
{
protected function globalMiddleware(): array
{
return [
ProfilerMiddleware::class, // <================
// ...
];
}
// ...
}
namespace App\Application\Bootloader;
use Spiral\Bootloader\Http\RoutesBootloader as BaseRoutesBootloader;
use Spiral\Profiler\ProfilerMiddleware;
final class RoutesBootloader extends BaseRoutesBootloader
{
protected function middlewareGroups(): array
{
return [
'web' => [
// ...
],
'profiler' => [ // <================
ProfilerMiddleware::class,
'middleware:web',
],
];
}
// ...
}
use Spiral\Router\Annotation\Route;
final class UserController
{
#[Route(route: '/users', name: 'user.store', methods: ['POST'], middleware: \Spiral\Profiler\ProfilerMiddleware::class)]
public function store(...): void
{
// ...
}
}