1. Go to this page and download the library: Download alex-frolov/query-guard library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
alex-frolov / query-guard example snippets
use QueryGuard\Query\QueryEvent;
use QueryGuard\QueryGuard;
QueryGuard::collector()->record(new QueryEvent(
sql: 'SELECT * FROM users WHERE id = ?',
params: [42],
durationMs: 0.4,
stack: debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),
));
use QueryGuard\Attribute\AllowQueries;
use QueryGuard\Attribute\IgnoreRule;
#[AllowQueries(50)]
#[IgnoreRule('n-plus-one')]
public function testImportsLargeFile(): void
// before: one query for the timesheets, then one per timesheet for its tags
foreach ($repository->findBy(['user' => $user]) as $timesheet) {
$names[] = implode(', ', $timesheet->getTags()->map(fn (Tag $t) => $t->getName())->toArray());
}
// after: the association is fetched with the parent, in one query
$timesheets = $repository->createQueryBuilder('t')
->addSelect('tags') // without addSelect the join filters but does not hydrate
->leftJoin('t.tags', 'tags')
->where('t.user = :user')->setParameter('user', $user)
->getQuery()->getResult();
// before: findOneBy in a loop
foreach ($ids as $id) { $orders[] = $repository->find($id); }
// after: one query, indexed for lookup
$orders = $repository->createQueryBuilder('o')
->where('o.id IN (:ids)')->setParameter('ids', $ids)
->indexBy('o', 'o.id')
->getQuery()->getResult();
// before
foreach (Order::all() as $order) { $total += $order->items->sum('price'); }
// after — eager load with the parent query
foreach (Order::with('items')->get() as $order) { $total += $order->items->sum('price'); }
// or, when the collection already exists
$orders->load('items');
#[AllowQueries(120)]
public function testBulkImport(): void
use QueryGuard\Attribute\AllowQueries;
use QueryGuard\Attribute\IgnoreRule;
// a budget sized to the test's real work — its actual count is in the log
#[AllowQueries(120)]
public function testBulkImport(): void
// switch off exactly the rule that misjudges this test; the argument is the rule id
// verbatim from the finding header: [warning] n-plus-one — ...
#[IgnoreRule('n-plus-one')]
public function testLegacyPdfExport(): void
// a whole class may carry the attributes instead of repeating them per test
#[IgnoreRule('select-star')]
final class ReportQueryTest extends TestCase
use PHPUnit\Framework\Attributes\Group;
#[Group('smoke')]
final class AuctionBidLoadSmokeTest extends TestCase
xml
<parameter name="skip-paths" value="vendor/api-platform,vendor/sonata-project"/>