PHP Cheatsheet
HTTP, CLI, and Dates
Use this PHP reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Request Method Routing
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; if ($method === 'POST') { // handle form or JSON body } elseif ($method === 'GET') { // render page or read query params } else { http_response_code(405); }
Keep routing decisions explicit. Do not trust method override headers unless your framework intentionally supports them.
Reading JSON Bodies
$raw = file_get_contents('php://input'); $payload = json_decode($raw, true, flags: JSON_THROW_ON_ERROR); $email = $payload['email'] ?? null;
$_POST is for form-encoded requests. JSON APIs usually read php://input and decode it manually or through a framework request object.
Query Strings and URLs
$query = http_build_query(['page' => 2, 'q' => 'php']); $url = '/search?' . $query; $parts = parse_url('https://example.com/path?a=1'); parse_str($parts['query'] ?? '', $params);
Use helpers to build and parse URLs instead of concatenating unescaped user input.
CLI Arguments
// php script.php input.csv --dry-run $script = $argv[0]; $args = array_slice($argv, 1); $options = getopt('', ['dry-run', 'output:']);
$argv is available in CLI mode. getopt handles simple flags; larger CLIs usually use Symfony Console.
Reading Stdin
$line = trim(fgets(STDIN)); // one line $answer = readline('Continue? [y/N] '); // prompt + read (CLI) while (($line = fgets(STDIN)) !== false) { // until EOF $n = (int) $line; } $all = stream_get_contents(STDIN); // everything at once
fgets returns the line including its trailing newline, so trim before parsing. fgets(STDIN) returns false at end of input.
DateTimeImmutable
$now = new DateTimeImmutable('now', new DateTimeZone('UTC')); $tomorrow = $now->modify('+1 day'); $due = $now->add(new DateInterval('P3DT12H')); // 3 days 12 hours echo $tomorrow->format(DateTimeInterface::ATOM); // 2026-07-06T00:00:00+00:00 echo $now->format('Y-m-d H:i:s');
Prefer DateTimeImmutable so date operations return new values instead of mutating shared objects.
Parsing Dates
$dt = DateTimeImmutable::createFromFormat('m/d/Y', '07/05/2026', new DateTimeZone('UTC')); if ($dt === false) { /* input did not match the format */ } $loose = new DateTimeImmutable('2026-07-05 14:30'); // ISO-ish strings parse directly
createFromFormat returns false on bad input, so always check before using the result. Format characters mirror format(): Y year, m month, d day, H:i:s time.
Diffs and Timestamps
$interval = $start->diff($end); // DateInterval $interval->days; // total whole days echo $interval->format('%a days, %h hours'); $ts = $now->getTimestamp(); // Unix seconds $fromTs = new DateTimeImmutable('@' . $ts); // UTC $fromTs = (new DateTimeImmutable())->setTimestamp($ts); time(); // current Unix timestamp
diff() works across time zones because both objects represent absolute instants. The @timestamp constructor always yields UTC.
Time Zones
$tz = new DateTimeZone('America/Los_Angeles'); $local = $now->setTimezone($tz);
Store instants in UTC when possible. Convert to a user timezone only at display boundaries.
File Uploads
if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) { $tmp = $_FILES['avatar']['tmp_name']; $name = basename($_FILES['avatar']['name']); move_uploaded_file($tmp, __DIR__ . '/uploads/' . $name); }
Validate MIME type, size, extension, and destination. Never trust the original filename as safe storage input.
HTTP Clients
composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client(['timeout' => 5]); $response = $client->get('https://api.example.com/health'); $body = (string) $response->getBody();
Set timeouts on outbound HTTP. Production code should also handle non-2xx responses and retries with backoff.