Shomer (שומר) means "Guardian" in Hebrew
Your SQL Query Guardian - Runtime validation and security for PHP development. Catch SQL errors and security issues before they reach production.
French citation : "Il ne dort ni ne sommeille le Gardien ..."
Just as a guardian protects and watches over, Shomer vigilantly protects your application by validating SQL queries during development, catching errors and security issues before they reach production.
In the Hebrew tradition, a Shomer (שומר) is a vigilant guardian who watches and protects. PHP Shomer applies this same vigilance to your SQL queries, acting as a silent guardian during development, ready to alert you at the slightest danger.
- 🛡️ Guards against SQL injection patterns
- 👁️ Watches for syntax errors
- ⚔️ Protects with prepared statement validation
- 📧 Alerts via email for critical issues
- 🎓 Teaches best practices
- 💡 Suggests secure query fixes (verbose mode)
- 🚀 Zero performance impact in production
- 💯 100% compatible with PDO and MySQLi
- 📍 Auto-captures execution context (file, line, URL, function) for instant debugging
composer require yd-shomer/php-shomer<?php
require 'vendor/autoload.php';
use Shomer\QueryValidator;
// Enable Shomer in development
define('SHOMER_ENABLED', true);
// Validate a prepared statement
$report = QueryValidator::validate([
'sql' => "INSERT INTO users (name, email) VALUES (?, ?)",
'params' => ['John Doe', '[email protected]']
], true, true);
if ($report['status'] === 'error') {
echo "⚠️ Query validation failed!\n";
print_r($report['erreurs']);
}// Simply set to false - zero overhead!
define('SHOMER_ENABLED', false);use Shomer\QueryValidator;
$query = [
'sql' => "SELECT * FROM users WHERE email = :email AND status = :status",
'params' => [
'email' => '[email protected]',
'status' => 'active'
]
];
$report = QueryValidator::validate($query, true, true);$query = [
'sql' => "INSERT INTO users (name, email, age) VALUES (?, ?, ?)",
'params' => ['John', '[email protected]'] // ⚠️ Missing parameter!
];
$report = QueryValidator::validate($query, true);
// Shomer will detect: "CRITICAL ERROR: Placeholder count (3) differs from parameter count (2)"$query = [
'sql' => "SELECT * FROM users WHERE username = ?",
'params' => ["admin' OR '1'='1"] // ⚠️ Injection attempt
];
$report = QueryValidator::validate($query, true, true);
// Shomer will warn: "SQL keyword 'OR' detected in parameter"$unsafeQuery = "SELECT * FROM users WHERE id = " . $_GET['id'];
$report = QueryValidator::validate($unsafeQuery, true);
// Shomer will alert: "SECURITY WARNING: Non-prepared query detected"// Send error reports via email
$report = QueryValidator::validate($query, true, true, 1);
// Or use custom email function
$report = QueryValidator::validate($query, true, true, 'my_custom_email_function');<?php
// config.php
// Enable/disable Shomer
define('SHOMER_ENABLED', true); // false in production
// Email configuration (optional)
define('SHOMER_EMAIL', '[email protected]');
define('SHOMER_EMAIL_FROM', '[email protected]');use Shomer\QueryValidator;
use Shomer\Reports\ValidationReport;
// Validate with full details
$report = QueryValidator::validate(
$query, // Query array or string
true, // Enable validation
true, // Verbose mode (all details)
'send_alert' // Custom email function
);
// Access report data
if ($report['nb_erreurs'] > 0) {
foreach ($report['erreurs'] as $error) {
error_log("Shomer Alert: $error");
}
}
if ($report['nb_avertissements'] > 0) {
foreach ($report['avertissements'] as $warning) {
error_log("Shomer Warning: $warning");
}
}- ✅ Placeholder count matches parameter count
- ✅ No mixing of
?and:namedplaceholders - ✅ No hardcoded values in prepared queries
- ✅ No unescaped PHP variables in query string
- ✅ Balanced parentheses
- ✅ Balanced quotes (single and double)
- ✅ Proper INSERT field/value count matching
- ✅ WHERE clause presence in UPDATE/DELETE
- ✅ SQL injection pattern detection
- ✅ Dangerous SQL keywords in parameters
- ✅ Superglobal variables in queries
- ✅ Unescaped user input
- ✅ Encourages prepared statements over raw queries
- ✅ Warns about
SELECT *usage - ✅ Detects missing WHERE in UPDATE/DELETE
- ✅ Educational error messages
[
'status' => 'error', // 'success', 'error', or 'bypassed'
'is_prepared' => true, // Is it a prepared statement?
'query' => 'SELECT ...', // The SQL query
'params' => [...], // Parameters (if prepared)
'erreurs' => [...], // Array of errors
'avertissements' => [...], // Array of warnings
'infos' => [...], // Detailed information (if verbose)
'nb_erreurs' => 2, // Error count
'nb_avertissements' => 1, // Warning count
'timestamp' => '2025-01-15 14:30:00',
'context' => [ // Execution context (NEW!)
'file' => '/path/to/script.php', // Absolute path
'file_relative' => './src/UserService.php', // Relative path
'line' => 42, // Line number
'function' => 'validateUser', // Function name
'class' => 'App\\UserService', // Class name (if method)
'type' => '->', // Method type (-> or ::)
'url' => 'https://example.com/login', // URL (web context)
'method' => 'POST', // HTTP method
'script_name' => '/var/www/public/index.php' // Script path
]
]Shomer automatically captures where the query validation was called:
- File & Line: Exact location in your code
- Function/Method: Which function or method called the validation
- URL: The request URL (in web context)
- HTTP Method: GET, POST, etc. (in web context)
- Script: The CLI script path (in CLI context)
This means debugging is instant - no need to search through your codebase! The error report comes "ready to use" with all the information you need.
Example email alert:
📍 EXECUTION CONTEXT:
───────────────────────────────────────────────────
📄 File: ./src/Services/UserService.php
📍 Line: 42
🔧 Method: App\Services\UserService->validateLogin()
🌐 URL: https://example.com/api/login
📝 Method: POST
───────────────────────────────────────────────────
When verbose mode is enabled, Shomer doesn't just tell you what's wrong—it shows you how to fix it!
For each detected issue, Shomer provides:
- ✅ Secure SQL - The corrected query
- ✅ PHP Code Example - Ready-to-use implementation
- ✅ Explanation - Why this approach is better
Example:
// Your problematic query
$query = "DELETE FROM users"; // Missing WHERE clause!
$report = QueryValidator::validate($query, true, true); // verbose = true
// Shomer provides a suggestion:
$report['suggestion'] = [
'query' => 'DELETE FROM users WHERE id = ?',
'code' => '$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);',
'explanation' => 'CRITICAL: DELETE without WHERE clause will affect ALL rows...'
];Suggestions are provided for:
- Non-prepared queries → Convert to prepared statements
- Parameter count mismatches → Fix parameter arrays
- Missing WHERE clauses → Add proper conditions
- SELECT * usage → Specify columns explicitly
- Hardcoded values → Use placeholders
- Field count errors → Match fields and values
This makes Shomer not just a validator, but a teaching tool that helps you learn secure SQL practices!
Shomer is a development tool, not a replacement for proper security practices:
✅ DO: Use Shomer during development to catch issues early
✅ DO: Always use prepared statements in production
✅ DO: Disable Shomer in production (SHOMER_ENABLED = false)
✅ DO: Validate and sanitize user input
❌ DON'T: Rely solely on Shomer for production security
❌ DON'T: Use raw SQL queries in production
❌ DON'T: Trust user input without validation
Development Mode (SHOMER_ENABLED = true):
- Full validation and analysis
- Detailed error reporting
- ~0.001-0.005 seconds per query
Production Mode (SHOMER_ENABLED = false):
- Instant bypass with single condition check
- ~0.0000002 seconds per query (negligible)
- Zero memory overhead
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
# Run tests
composer test
# Run tests with coverage
composer test-coverageThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the Hebrew concept of Shomer (שומר) - Guardian
- Built with ❤️ for the PHP community
- Special thanks to all contributors
Shomer: Because your database deserves a guardian.
שומר - Protecting your queries, one validation at a time.