Anki Cards: PHP Core Terminology Core Terminology 📌 In web PHP, a single execution of code to respond to an HTTP request is often called a {{c1::request}} (or script run). PHP runs via an {{c1::interpreter}} (the PHP engine), not by producing a native binary like C/C++. PHP is {{c1::server-side}}: the browser receives the {{c2::output}} (HTML/JSON), not the {{c3::PHP source}}. Built-in arrays that are always available (e.g., $_GET, $_POST, $_SERVER) are called {{c1::superglobals}}. PHP’s automatic conversion between types (e.g., string ↔ int) is {{c1::type juggling}}. declare(strict_types=1); enables {{c1::strict typing}} behavior for {{c2::scalar type hints}}. Validation asks: {{c1::“Is this allowed?”}}; invalid input is typically {{c2::rejected}}. Sanitization asks: {{c1::“Can we make this safe/clean?”}}; input is {{c2::transformed}}. Escaping asks: {{c1::“How do I safely output this in a context?”}} (HTML/attr/JS/URL), and is done at {{c2::output time}}. XSS happens when unescaped output lets an attacker run {{c1::JavaScript}} in the victim’s browser. CSRF is a {{c1::forged request}} problem; typical defense is a per-request {{c2::token/nonce}}. SQL injection is prevented by using {{c1::prepared statements}} instead of unsafe string concatenation. require is {{c1::fatal}} if the file is missing; include emits a {{c2::warning}} and continues. Composer-style class loading is {{c1::autoloading}}, commonly via {{c2::PSR-4}}. A {{c1::namespace}} prevents naming collisions by qualifying names like MyApp\Foo. {{c1::Dependency injection}} means {{c2::passing dependencies in}} rather than creating them inside the class/function. {{c1::PDO}} is PHP’s standard DB interface and supports {{c2::prepared statements}}. In WordPress, a hook is a {{c1::callback point}}: an {{c2::action}} “does something,” a {{c3::filter}} “modifies a value.” Daily PHP Constructs (“Commands”) 🧠 echo outputs {{c1::strings}} (and can output multiple args separated by commas). print is like echo but returns {{c1::1}} (so it’s usable in expressions). var_dump($x) shows both {{c1::type}} and {{c2::value}} (great for debugging). print_r($x, true) returns the output as a {{c1::string}} when the second argument is {{c2::true}}. die() / exit() {{c1::stops execution}} immediately (often after a redirect). include_once / require_once ensure a file is included at most {{c1::once}} per request. Control Flow (If / Switch / Match / Loops) 🔁 if (...) {} runs only when the condition is {{c1::true}}. switch typically needs {{c1::break}} to avoid fall-through into the next case. match (...) { ... } is an {{c1::expression}} that {{c2::returns a value}} (unlike switch). match uses {{c1::strict comparisons}} (no type juggling like loose switch cases can do). foreach ($arr as $value) iterates over the array’s {{c1::values}}. foreach ($arr as $k => $v) gives both the {{c1::key}} and the {{c2::value}}. break exits the {{c1::current loop/switch}}; continue skips to the {{c2::next iteration}}. A do { ... } while (...); loop runs the body at least {{c1::once}}. Functions & Organization 🧩 A function can define a default parameter like function f($x = 123), meaning it’s {{c1::optional}} when calling. return exits a function and optionally provides a {{c1::value}}. global $x; accesses a variable from the {{c1::global scope}} (best used {{c2::sparingly}}). static $x = 0; inside a function persists {{c1::between calls}} during the same request. A function with a return type : int promises it will return an {{c1::integer}} (or throw). In modern PHP, use {{c1::strict_types}} when you want stricter scalar parameter/return behavior. Error Handling & Exceptions 🚧 try { ... } catch (Throwable $e) { ... } catches both {{c1::Exception}} and many {{c2::Error}} types. finally { ... } runs whether an exception was {{c1::thrown}} or not (good for cleanup). throw new Exception('msg'); {{c1::raises}} an exception to be handled by a caller. If an exception is not caught, it typically causes a {{c1::fatal error}} and aborts the request. OOP: Classes, Visibility, Inheritance 🧱 new ClassName() creates an {{c1::object instance}}. public members are accessible {{c1::everywhere}}; protected inside {{c2::class + subclasses}}; private only inside the {{c3::declaring class}}. extends means {{c1::inheritance}}; implements means fulfilling an {{c2::interface contract}}. $this-> accesses the {{c1::current object}} instance members. self:: refers to the {{c1::current class}}; parent:: refers to the {{c2::parent class}}. A trait is a mechanism for {{c1::code reuse}} across classes (without inheritance). An abstract class cannot be {{c1::instantiated}} directly. An interface defines {{c1::method signatures}} that implementing classes must provide. Variables, Types, Operators 🧱 PHP variables start with a {{c1::$}} sign. define('APP_ENV', 'dev') defines a {{c1::constant}} at runtime; const defines a constant at {{c2::compile time}} (and can be used in classes). Scalar types: {{c1::int}}, {{c2::float}}, {{c3::string}}, {{c4::bool}}. null represents an {{c1::absence}} of value. . is {{c1::string concatenation}} in PHP. .= performs concatenation and {{c1::assignment}} in one step. == is {{c1::loose comparison}} (type juggling); === is {{c2::strict}} (type + value). The “spaceship” operator <=> returns {{c1::-1}}, {{c2::0}}, or {{c3::1}} for ordering comparisons. Null coalescing ?? uses the right-hand side only if the left is {{c1::null or undefined}}. Nullsafe ?-> stops and returns {{c1::null}} if the left side is {{c2::null}}. && / || are {{c1::short-circuit}} boolean operators. The ternary cond ? a : b picks {{c1::a}} when cond is true, else {{c2::b}}. Strings 🧵 In single quotes '...', variables are generally {{c1::not interpolated}}. In double quotes "...", variables like $name are {{c1::interpolated}}. strlen($s) returns the string length in {{c1::bytes}} (multibyte text may need {{c2::mb_strlen}}). strpos($haystack, $needle) returns the position or {{c1::false}} (so use === false checks). trim($s) removes whitespace from the {{c1::start and end}} of a string. explode(',', $s) converts a string into an {{c1::array}}. implode(',', $arr) converts an array into a {{c1::string}}. sprintf("Hi %s", $name) returns a formatted {{c1::string}} without echoing it. Arrays (Workhorse) 🧰 [] creates an {{c1::array}} literal (indexed or associative). Indexed array example: $a = [10, 20, 30]; uses numeric {{c1::indexes}}. Associative array example: ['name' => 'Ada'] uses string {{c1::keys}}. $a[] = 99; appends to the {{c1::end}} of an indexed array. count($arr) returns the number of {{c1::elements}}. in_array($needle, $haystack, true) uses strict checking when the third argument is {{c1::true}}. array_key_exists('k', $arr) checks for the presence of a {{c1::key}} even if its value is {{c2::null}}. array_map(fn($x) => ..., $arr) transforms each element and returns a {{c1::new array}}. array_filter($arr, $fn) keeps elements where the callback returns {{c1::true}}. array_reduce($arr, $fn, $initial) folds an array into a single {{c1::value}}. sort($arr) sorts values and {{c1::reindexes}} numeric keys. asort($arr) sorts by value while {{c1::preserving keys}}. ksort($arr) sorts by {{c1::key}}. HTTP & Superglobals 🌐 Query string parameters are read from {{c1::$_GET}}. Form body parameters are commonly read from {{c1::$_POST}}. Request metadata (method, headers info, URI) is found in {{c1::$_SERVER}}. Uploaded file info is in {{c1::$_FILES}} (name/type/tmp_name/error/size). Session data uses {{c1::$_SESSION}} after calling {{c2::session_start()}}. A safe read pattern: $q = $_GET['q'] ?? ''; avoids an {{c1::undefined index}} notice. header('Location: /path'); triggers an HTTP {{c1::redirect}}. After sending a Location header, you should call {{c1::exit}} to stop further output. http_response_code(404); sets the HTTP status code to {{c1::404}}. Security Defaults 🛡️ For HTML output, htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') prevents {{c1::XSS}} in HTML/text contexts. ENT_QUOTES escapes both {{c1::single}} and {{c2::double}} quotes. Passwords should be stored using {{c1::password_hash}} (not md5/sha1). Verify a password with {{c1::password_verify($pw, $hash)}}. SQL safety best practice: use {{c1::prepared statements}} with bound parameters (not string concatenation). CSRF defense: include a per-request {{c1::token}} and verify it on submission. Never trust $_GET/$_POST types: always {{c1::validate}} and/or {{c2::cast}} (e.g., (int)). Output escaping is {{c1::context-dependent}} (HTML vs attribute vs URL vs JS). Composer & Autoloading ⚙️ composer.json declares dependencies and {{c1::autoload rules}}. composer.lock pins the {{c1::exact versions}} installed. Composer’s autoloader entry file is {{c1::vendor/autoload.php}}. In code, require __DIR__ . '/vendor/autoload.php'; enables {{c1::autoloading}}. PSR-4 maps {{c1::namespaces}} to {{c2::directory paths}}. PDO (Database) 🗄️ In PDO, setting PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION makes DB errors throw {{c1::exceptions}}. A prepared statement is created with $pdo->{{c1::prepare}}(...). Parameters are provided via $stmt->{{c1::execute}}(['email' => $email]) (named placeholders). Fetching one row as an associative array can be done with $stmt->fetch(PDO::{{c1::FETCH_ASSOC}}). After an INSERT, $pdo->{{c1::lastInsertId}}() gets the last generated ID (driver-dependent). WordPress Parallels 🧩 WordPress actions are registered with {{c1::add_action}}; filters with {{c2::add_filter}}. A filter callback must {{c1::return}} the modified value; an action callback typically {{c2::does not}}. WordPress escaping helpers: esc_html, esc_attr, {{c1::esc_url}} for URLs. WordPress sanitizers include sanitize_text_field and {{c1::sanitize_email}}. WordPress CSRF protection uses {{c1::nonces}} (e.g., wp_nonce_field, check_admin_referer). $wpdb->prepare(...) is the WordPress pattern for {{c1::safe SQL}}. “I Forget This” Reminders 🗂️ Prefer the full opening tag {{c1:: to avoid accidental {{c1::whitespace output}}. In PHP, the string '0' is {{c1::falsy}} (so strict comparisons can matter). HTTP headers must be sent before any {{c1::output}} (even whitespace), otherwise you get “headers already sent.” Extra High-Value Additions (Fits the Topic) ✨ error_reporting(E_ALL); and ini_set('display_errors', '1'); are useful in {{c1::development}} (but not in production). Prefer filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS) for simple input handling, but still {{c1::validate}} properly. json_encode($data, JSON_UNESCAPED_UNICODE) produces {{c1::JSON}} output; set header Content-Type: application/json. To read JSON request bodies: $raw = file_get_contents('php://input'); $data = json_decode($raw, true);— true yields an {{c1::associative array}}. isset($x) is false if $x is {{c1::not set}} or {{c2::null}}. empty($x) treats values like 0, '0', [], and null as {{c1::empty}} (be careful). Use === when checking strpos(...) results because position {{c1::0}} is a valid match but is {{c2::falsy}}. The directory constant __DIR__ gives the current file’s {{c1::directory path}} (safer than relative paths). require vs require_once: require_once adds overhead; prefer {{c1::autoloading}} for classes instead of many *_once. Use password_hash with PASSWORD_DEFAULT so the algorithm can {{c1::upgrade over time}}. In prepared statements, never interpolate variables directly into SQL; bind them as {{c1::parameters}}. In PHP 8+, match has no fall-through and will throw UnhandledMatchError if no case matches and there’s no {{c1::default}}. For arrays, === compares both order and types; for “same key/value pairs regardless of order,” use {{c1::ksort}} first. In OOP, prefer constructor injection: __construct(private Logger $logger) is promoted property syntax (PHP {{c1::8.0+}}). For safe redirects, validate destination URLs to prevent {{c1::open redirect}} vulnerabilities. If you tell me whether you’re using PHP 7.4, 8.0–8.4, and whether you’re focusing on WordPress plugin/theme dev or general backend, I can generate a second deck with scenario-based clozes (debugging, forms, auth, PDO pitfalls) 🧠✅