पाठ 18 / 25
Files, Dates and Times
Read and write files safely and handle dates with DateTimeImmutable and time zones.
Two everyday sources of bugs
For files, file_get_contents and file_put_contents handle small files; for large ones, stream line by line with SplFileObject or fopen/fgets, often wrapped in a generator (yield) so memory stays constant. Write important files atomically (write to a temporary file in the same directory, then rename), use LOCK_EX when appending from several processes, and never build paths from user input without validating them, to prevent directory traversal (../../etc/passwd). For uploads, check $_FILES['x']['error'], verify size and real content type (with finfo), generate your own file names and move them with move_uploaded_file to storage outside the web root or to object storage such as S3. For dates, prefer DateTimeImmutable, which returns new objects instead of mutating, avoiding a classic class of bugs. Always be explicit about time zones: store timestamps in UTC and convert to Asia/Kolkata (or the user's zone) for display. Use DateInterval and DatePeriod for arithmetic and ranges; the Carbon library adds convenient helpers on top.
Streaming a CSV with a generator and handling dates
Constant memory for big files; UTC storage, local display.
<?php
declare(strict_types=1);
/** @return Generator<int, array<string, string>> */
function readCsv(string $path): Generator
{
$file = new SplFileObject($path);
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::READ_AHEAD);
$headers = null;
foreach ($file as $row) {
if ($headers === null) { $headers = $row; continue; }
yield array_combine($headers, $row);
}
}
foreach (readCsv('/data/imports/orders.csv') as $line) {
$importer->import($line); // one row in memory at a time
}
$placedAtUtc = new DateTimeImmutable('2026-10-03 06:45:00', new DateTimeZone('UTC'));
$local = $placedAtUtc->setTimezone(new DateTimeZone('Asia/Kolkata'));
echo $local->format('d M Y, h:i A'), PHP_EOL; // 03 Oct 2026, 12:15 PM
$dueDate = $placedAtUtc->add(new DateInterval('P30D')); // $placedAtUtc is unchangedDateTime mutates, DateTimeImmutable does not
$due = $date->modify('+30 days'); with DateTime also changes $date, silently breaking other code that holds it. DateTimeImmutable returns a new object, so the original stays correct.
त्वरित जाँच: Why is DateTimeImmutable generally preferred over DateTime?
- Its methods return new objects instead of modifying the original, avoiding shared-state bugs
- It supports more time zones
- It is required for UTC
- It formats dates faster
Answer
Its methods return new objects instead of modifying the original, avoiding shared-state bugs — Immutable date objects cannot be changed accidentally by other code.