All skills
asyrafhussin avatar

/php-best-practices

@e7ea05d

PHP 8.x modern patterns, PSR standards, and SOLID principles. Use when reviewing PHP code, checking type safety, auditing code quality, or ensuring PHP best practices. Triggers on "review PHP", "check PHP code", "audit PHP", or "PHP best practices".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/php-best-practices

This session only. Nothing lands on disk.

rulessec-sql-prepared.md

≈674 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Prepared Statements

Always use prepared statements with parameter binding for SQL queries. Never concatenate user input into SQL strings.

Bad Example

<?php

declare(strict_types=1);

// String concatenation - SQL injection vulnerable
$email = $_POST['email'];
$result = $db->query("SELECT * FROM users WHERE email = '$email'");
// Input: ' OR '1'='1  →  SELECT * FROM users WHERE email = '' OR '1'='1'

// Variable interpolation - equally vulnerable
$id = $_GET['id'];
$result = $db->query("SELECT * FROM orders WHERE id = $id");
// Input: 1; DROP TABLE orders  →  catastrophic

// sprintf - still vulnerable
$sql = sprintf("SELECT * FROM users WHERE name = '%s'", $name);

// Even with type casting - fragile and error-prone
$id = (int) $_GET['id']; // What if you forget the cast?

Good Example

<?php

declare(strict_types=1);

// PDO with named parameters
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();

// PDO with positional parameters
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ? AND status = ?');
$stmt->execute([$id, $status]);

// Explicit type binding for non-string values
$stmt = $pdo->prepare('SELECT * FROM orders WHERE total > :min LIMIT :limit');
$stmt->bindValue(':min', $minAmount, PDO::PARAM_STR);
$stmt->bindValue(':limit', $pageSize, PDO::PARAM_INT);
$stmt->execute();

// INSERT with prepared statement
$stmt = $pdo->prepare(
    'INSERT INTO users (name, email, created_at) VALUES (:name, :email, NOW())'
);
$stmt->execute([
    'name' => $name,
    'email' => $email,
]);

// PDO configuration for maximum safety
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false, // Use real prepared statements
]);

// Dynamic column names - whitelist, never bind
$allowed = ['name', 'email', 'created_at'];
$column = in_array($sortBy, $allowed, true) ? $sortBy : 'id';
$stmt = $pdo->prepare("SELECT * FROM users ORDER BY {$column} ASC");

Why

  • SQL Injection Prevention: Parameters are never interpreted as SQL
  • Automatic Escaping: Database driver handles escaping correctly
  • Performance: Prepared statements can be reused for repeated queries
  • EMULATE_PREPARES = false: Forces real server-side preparation
  • Column Names: Cannot be parameterized - must use whitelist validation

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill is a comprehensive and safe resource for PHP 8.x best practices. It provides structured guidance on type safety, modern PHP syntax, PSR standards, and secure coding practices (such as prepared statements and password hashing). The agent is instructed to use standard environment detection commands (php -v, grep) to tailor its advice. No malicious patterns or security risks were identified.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    39 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e7ea05d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
Other metadata
metadata
{
  "author": "php-community",
  "version": "2.1.0",
  "phpVersion": "8.0 - 8.5"
}

README badge

README badge for asyrafhussin/agent-skills/php-best-practices