Try it yourself with our free Sql Formatter tool — runs entirely in your browser, no signup needed.

How to Format SQL queries in PHP

How to format SQL queries in PHP

Formatting SQL queries in PHP is an essential skill for any developer working with databases. Well-formatted queries improve readability, maintainability, and even performance. In this guide, we will walk through the best practices for formatting SQL queries in PHP, covering the most common use cases and edge cases.

Quick Example

<?php
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;

// Install Doctrine DBAL using Composer: composer require doctrine/dbal

// Create a connection to the database
$conn = new Connection([
    'driver' => 'pdo_sqlite',
    'path' => 'example.db',
]);

// Create a query builder
$qb = $conn->createQueryBuilder();

// Define the query
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', 'john@example.com')
    ->getQuery();

// Execute the query
$result = $query->execute();

// Print the result
print_r($result->fetchAll());

This example demonstrates the most common use case: creating a simple query using Doctrine's QueryBuilder.

Step-by-Step Breakdown

Let's walk through the code line by line:

  1. use Doctrine\DBAL\Connection; and use Doctrine\DBAL\Query\QueryBuilder;: We import the necessary classes from Doctrine DBAL.
  2. $conn = new Connection([...]);: We create a connection to the database using the Connection class. We pass an array of configuration options, including the driver and path to the database file.
  3. $qb = $conn->createQueryBuilder();: We create a query builder instance using the createQueryBuilder method of the connection object.
  4. $query = $qb->select('u.id', 'u.name'): We define the query using the select method of the query builder. We specify the columns to select using an array of strings.
  5. ->from('users', 'u'): We specify the table to query using the from method. We also define an alias for the table using the second argument.
  6. ->where('u.email = :email'): We add a condition to the query using the where method. We use a named parameter :email to avoid SQL injection.
  7. ->setParameter('email', 'john@example.com'): We set the value of the named parameter using the setParameter method.
  8. ->getQuery(): We get the final query object using the getQuery method.
  9. $result = $query->execute();: We execute the query using the execute method of the query object.
  10. print_r($result->fetchAll());: We print the result of the query using the fetchAll method of the result object.

Handling Edge Cases

Empty/null input

$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', null); // or ''

In this example, we set the value of the named parameter to null or an empty string. This will result in a query that selects all rows from the users table.

Invalid input

$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', ' invalid input ');

In this example, we set the value of the named parameter to an invalid input (e.g., a string with spaces). This will result in a query that selects no rows from the users table.

Large input

$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', str_repeat('a', 1000)); // large input

In this example, we set the value of the named parameter to a large input (e.g., a string with 1000 characters). This will result in a query that selects no rows from the users table.

Unicode/special characters

$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', 'john@example.com with unicode ');

In this example, we set the value of the named parameter to a string with Unicode characters. This will result in a query that selects no rows from the users table.

Common Mistakes

1. Not using named parameters

// Wrong
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where("u.email = '$email'");

// Corrected
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', $email);

Not using named parameters can lead to SQL injection vulnerabilities.

2. Not escaping special characters

// Wrong
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where("u.email = '$email'");

// Corrected
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', $email);

Not escaping special characters can lead to SQL injection vulnerabilities.

3. Not handling null values

// Wrong
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', $email);

// Corrected
$query = $qb
    ->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = :email')
    ->setParameter('email', $email ?: '');

Not handling null values can lead to unexpected query behavior.

Performance Tips

  1. Use prepared statements: Prepared statements can improve performance by reducing the overhead of parsing and compiling SQL queries.
  2. Use indexing: Indexing can improve performance by reducing the time it takes to execute queries.
  3. Optimize query execution: Optimizing query execution can improve performance by reducing the number of database queries and the amount of data transferred.

FAQ

Q: What is the difference between execute and executeQuery?

A: execute executes the query and returns a result object, while executeQuery executes the query and returns a query result object.

Q: How do I handle null values in my query?

A: You can handle null values by using the ?: operator to set a default value for the parameter.

Q: Can I use Doctrine DBAL with other databases?

A: Yes, Doctrine DBAL supports multiple databases, including MySQL, PostgreSQL, and SQLite.

Q: How do I optimize my queries for performance?

A: You can optimize your queries by using prepared statements, indexing, and optimizing query execution.

Q: What is the difference between setParameter and setParameters?

A: setParameter sets a single parameter, while setParameters sets multiple parameters.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp