ACTIVATE when writing SQL queries in PHP code, using Doctrine DBAL, or formatting database queries. ACTIVATE for 'SQL', 'query', 'DBAL', 'JOIN', 'SELECT'. Covers: query direction convention (start from known entity), nowdoc formatting for SQL, column listing, JOIN ordering. DO NOT use for: Doctrine ORM/DQL, database migrations, general PHP code conventions.
From phpnpx claudepluginhub fabiensalles/claude-marketplace --plugin phpThis skill uses the workspace's default tool permissions.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Designs, audits, and improves analytics tracking systems using Signal Quality Index for reliable, decision-ready data in marketing, product, and growth.
Enforces A/B test setup with gates for hypothesis locking, metrics definition, sample size calculation, assumptions checks, and execution readiness before implementation.
Conventions for SQL queries written in PHP code (Doctrine DBAL).
IMPORTANT: Always start queries from the known/main entity and navigate to related entities via JOINs.
When you have access to a specific entity (via ID or UUID), start the query from that entity's table and JOIN towards the data you need.
Context: You have a $orderId and want to fetch associated buyers.
// Start from orders (known entity) -> navigate to buyer
FROM orders o
INNER JOIN shipping_group sg ON sg.id = o.shipping_group_id
INNER JOIN shipping_item si ON si.shipping_group_id = sg.id
INNER JOIN buyer b ON b.id = si.buyer_id
WHERE o.id = :order_id
// Start from buyer (unknown) -> navigate back to orders
FROM buyer b
INNER JOIN shipping_item si ON si.buyer_id = b.id
INNER JOIN shipping_group sg ON sg.id = si.shipping_group_id
INNER JOIN orders o ON o.shipping_group_id = sg.id
WHERE o.id = :order_id
IMPORTANT: Follow PER Coding Style - Section 10 for nowdoc/heredoc formatting.
See code-conventions skill for complete PER rules.
<<<'SQL') - never heredoc (<<<SQL) for SQL queries:param) instead of variable interpolation$data = $connection->executeQuery(
<<<'SQL'
SELECT b.id, b.name
FROM buyer b
WHERE b.uuid = :uuid
SQL,
[
'uuid' => $uuid,
],
[
'uuid' => UuidType::NAME,
],
)->fetchAssociative();
One column per line for readability:
<<<'SQL'
SELECT
b.id,
b.first_name,
b.last_name,
BIN_TO_UUID(b.uuid) as uuid
FROM buyer b
SQL
b for buyer, o for orders)AS for column aliases: BIN_TO_UUID(b.uuid) AS uuidINNER JOIN, LEFT JOIN)FROM orders o
INNER JOIN shipping_group sg ON sg.id = o.shipping_group_id
INNER JOIN shipping_item si ON si.shipping_group_id = sg.id
LEFT JOIN buyer b ON b.id = si.buyer_id
| Rule | Description |
|---|---|
| Query direction | Start from known entity, JOIN to needed data |
| Nowdoc syntax | Use <<<'SQL' (nowdoc), never <<<SQL (heredoc) |
| Nowdoc format | See code-conventions for PER rules |
| Column listing | One per line for multi-column SELECT |
| Table aliases | Short, meaningful, always prefixed |
| JOIN order | Follow logical relationship path |