Practical PHP Notes: Commonly Used Syntax and Functions I Use in Real Projects - Featured Image

I’ve been writing PHP for many years now, and honestly, I’m not the kind of developer who memorizes syntax every day. Instead, whenever a certain feature shows up repeatedly in real projects, I make sure I truly understand it, double-check the details, and fine-tune how I use it.

This article is essentially my personal cheat sheet—a collection of PHP functions I use and look up most often when building systems, writing APIs, or integrating external services. I’m putting it all in one place mainly for myself, but hopefully it’ll be useful to you as well.

String Handling

            
                // Extract substrings
                substr($string, $offset, $length);
                mb_substr($string, $offset, $length, 'UTF-8');

                // Replace strings
                str_replace($search, $replace, $string);

                // Handle string length
                strlen($string);
                mb_strlen($string, 'UTF-8');

                // Trim whitespace
                trim($string)

                // Check if a string contains a keyword
                str_contains($string, 'keyword');

                // Check prefix / suffix
                str_starts_with($string, 'keyword');
                str_ends_with($string, 'keyword');

                // Case conversion
                strtolower($string)              // Convert to lowercase
                strtoupper($string)              // Convert to uppercase
                ucfirst($string)                 // Uppercase the first character

                // Split and join strings
                explode(',', $string);
                implode(',', $array);
            
        

JSON

            
                // Convert an array to JSON
                // JSON_UNESCAPED_UNICODE: keep Unicode characters readable
                // JSON_UNESCAPED_SLASHES: keep URLs readable
                // JSON_PRETTY_PRINT: formatted output
                json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

                // Decode JSON back into an array
                $array = json_decode($json, true);

                // Check if json_decode failed
                if ($array === null && json_last_error() !== JSON_ERROR_NONE) {
                    // Invalid JSON
                }
            
        

File Handling

Writing Files

                
                    // Write a file
                    file_put_contents(
                        'data.json',
                        json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
                    );

                    // Append to a file
                    // FILE_APPEND: append mode
                    // LOCK_EX: prevent race conditions
                    file_put_contents(
                        'app.log',
                        "[" . date('Y-m-d H:i:s') . "] something happened\n",
                        FILE_APPEND | LOCK_EX
                    );

                    // Write a CSV file
                    $fp = fopen('data.csv', 'w');
                    fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));   // UTF-8 BOM
                    fputcsv($fp, ['id', 'name', 'score']);
                    fputcsv($fp, [1, 'Mark', 95]);
                    fputcsv($fp, [2, 'Alex', 88]);
                    fclose($fp);
                
            

Reading Files

                
                    // Read entire file
                    $content = file_get_contents('data.json');

                    // Read line by line (method 1)
                    $lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
                    foreach ($lines as $line) {
                        echo $line;
                    }

                    // Read line by line (method 2 – better for large files)
                    $fp = fopen('data.txt', 'r');
                    while (($line = fgets($fp)) !== false) {
                        echo $line;
                    }
                    fclose($fp);

                    // Read CSV into an associative array
                    $fp = fopen('data.csv', 'r');
                    $header = fgetcsv($fp);         // First row is the header
                    $data = [];
                    while (($row = fgetcsv($fp)) !== false) {
                        $data[] = array_combine($header, $row);
                    }
                    fclose($fp);
                
            

Working with Timestamps

Basics

According to Wikipedia, a Unix timestamp is the number of seconds since January 1, 1970, 00:00:00 UTC.

If you want to add time, you can simply add seconds—or use strtotime, which is surprisingly powerful. PHP can parse almost any English time description into a Unix timestamp. Just remember: PHP always uses the server’s time and timezone, so make sure those are configured correctly.

                
                    // Convert time descriptions to timestamps
                    time();                                  // Current timestamp
                    strtotime('now');                        // Current timestamp
                    strtotime('2020-10-28 12:50:21');        // Specific datetime
                    strtotime('2020-10-28 14:00:00 +1 day'); // Add time

                    // Convert timestamps to formatted strings
                    date('Y-m-d H:i:s', time());
                    date('Y-m-d H:i:s', strtotime('2020-10-28 12:50:21'));
                
            

Modern Date/Time Handling (Recommended)

                
                    // Create DateTime objects
                    $dt = new DateTime('now', new DateTimeZone('Asia/Taipei'));
                    $dt = new DateTime('2025-01-10 08:30:00', new DateTimeZone('Asia/Taipei'));

                    // Create DateTime using a specific format
                    $dt = DateTime::createFromFormat(
                        'Y-m-d H:i:s',
                        '2025-01-10 08:30:00',
                        new DateTimeZone('Asia/Taipei')
                    );

                    // Format output
                    echo $dt->format('Y/m/d H:i:s');

                    // Add / subtract time
                    $dt = $dt->add(new DateInterval('P1D'));
                    $dt = $dt->sub(new DateInterval('P1D'));

                    // Date Difference
                    $dt1 = new DateTimeImmutable(
                        '2025-01-01 08:30:00',
                        new DateTimeZone('Asia/Taipei')
                    );
                    $dt2 = new DateTimeImmutable(
                        '2025-01-03 11:45:20',
                        new DateTimeZone('Asia/Taipei')
                    );
                    $interval = $dt2->diff($dt1);
                    $interval->y;    // Years
                    $interval->m;    // Months
                    $interval->d;    // Days (excluding years/months)
                    $interval->h;    // Hours
                    $interval->i;    // Minutes
                    $interval->s;    // Seconds
                    $interval->days; // Total days difference
                    echo $interval->format('%a days %h hours %i minutes %s seconds');

                    Date Comparison
                    if ($dt1 < $dt2) {
                    }
                
            

Notes

DateInterval string examples

  • P1Y2M3DT4H5M6S: 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds
  • P3DT6S: 3 days, 6 seconds
  • P3DT5M6S: 3 days, 5 minutes, 6 seconds

If there’s any time component, you must include T.

DateTime vs DateTimeImmutable

  • DateTime is mutable — modifying it changes the original object
  • DateTimeImmutable is immutable — modifications return a new object

Both implement DateTimeInterface, so you can safely compare them. Comparisons are based on actual time, not object identity.

Calling APIs with cURL

GET Example

                
                    $params = [
                        'foo1' => 'bar1',
                        'foo2' => 'bar2',
                        'foo3' => 'bar3',
                    ];
                    $queryString = http_build_query($params);

                    // cURL
                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_URL, URL . '?' . $queryString);
                    curl_setopt($curl, CURLOPT_TIMEOUT, 60);
                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($curl, CURLOPT_HTTPHEADER, [
                        'Authorization: Bearer ' . $token,
                        'Accept: application/json',
                    ]);
                    $response = curl_exec($curl);
                
            

POST Example

                
                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_URL, URL);
                    curl_setopt($curl, CURLOPT_POST, true);
                    curl_setopt($curl, CURLOPT_POSTFIELDS, [
                        'foo1' => 'bar1',
                        'foo2' => 'bar2',
                        'foo3' => 'bar3',

                        // Single file upload
                        'file' => new CURLFile($inputPath, mime_content_type($inputPath), basename($inputPath)),
                    ]);
                    curl_setopt($curl, CURLOPT_TIMEOUT, 60);
                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($curl, CURLOPT_HTTPHEADER, [
                        'Authorization: Bearer ' . $token,
                        'Accept: application/json',
                    ]);
                    $response = curl_exec($curl);
                
            
For uploading multiple files with cURL, please refer to the separate article for a detailed explanation.

Handling the Response

                
                    $response = curl_exec($curl);

                    // cURL execution error
                    if ($response === false) {
                        $errno  = curl_errno($curl);
                        $errmsg = curl_error($curl);
                        throw new Exception('cURL Error ' . $errno . ': ' . $errmsg);
                    }

                    // Check HTTP status code
                    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
                    if ($httpCode < 200 || $httpCode >= 300) {
                        throw new Exception("HTTP {$httpCode}: {$response}");
                    }

                    // Decode JSON response
                    $data = json_decode($response, true);
                    if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
                        throw new Exception('JSON decode error: ' . json_last_error_msg());
                    }

                    curl_close($curl);
                
            

Retrieving Headers

Request Headers

                
                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_URL, URL);
                    curl_setopt($curl, CURLINFO_HEADER_OUT, true);
                    $response = curl_exec($ch);
                    $requestHeader = curl_getinfo($ch, CURLINFO_HEADER_OUT);
                
            

Response Headers

                
                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_URL, URL);
                    curl_setopt($curl, CURLOPT_HEADER, true);
                    $response = curl_exec($curl);

                    $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
                    $header = substr($response, 0, $headerSize);
                    $body = substr($response, $headerSize);
                
            

Commonly Used curl_setopt() Options

Option Description
CURLOPT_VERBOSE Debug mode
CURLOPT_URL Target URL
CURLOPT_CONNECTTIMEOUT Max time to wait for connection
CURLOPT_TIMEOUT Max total request time
CURLOPT_HEADER Include response headers
CURLINFO_HEADER_OUT Retrieve outgoing request headers
CURLOPT_HTTPHEADER Set HTTP headers (don’t manually set Content-Type)
CURLOPT_RETURNTRANSFER Return response as a string
CURLOPT_POST Enable POST
CURLOPT_POSTFIELDS POST data
CURLOPT_CUSTOMREQUEST PUT, DELETE, PATCH, OPTIONS
CURLOPT_SSL_VERIFYPEER Verify SSL certificate
CURLOPT_SSL_VERIFYHOST Verify SSL host

Downloading Files

            
                $url = 'https://example.com/image.jpg';
                $savePath = __DIR__ . '/download/image.jpg';

                // Ensure directory exists
                if (!is_dir(dirname($savePath))) {
                    mkdir(dirname($savePath), 0755, true);
                }

                // cURL
                $fp = fopen($savePath, 'w');
                $ch = curl_init($url);
                curl_setopt($ch, CURLOPT_FILE, $fp);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                curl_exec($ch);
                if (curl_errno($ch)) {
                    throw new Exception(curl_error($ch));
                }

                curl_close($ch);
                fclose($fp);