Navigation

Php

How to Work with JSON Files

Handle JSON file operations in PHP with proper error handling, validation, and efficient processing for configuration files and data storage.

Table Of Contents

Quick Fix

JSON files are perfect for structured data storage and configuration. PHP's built-in JSON functions provide robust encoding and decoding with comprehensive error handling and performance optimization.

<?php

// Read JSON file safely
function readJSONFile(string $filename): array {
    if (!file_exists($filename)) {
        throw new InvalidArgumentException("JSON file not found: $filename");
    }
    
    $content = file_get_contents($filename);
    if ($content === false) {
        throw new RuntimeException("Cannot read JSON file: $filename");
    }
    
    $data = json_decode($content, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new RuntimeException("JSON decode error: " . json_last_error_msg());
    }
    
    return $data;
}

// Write JSON file with formatting
function writeJSONFile(string $filename, array $data, bool $prettyPrint = true): bool {
    $flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
    if ($prettyPrint) {
        $flags |= JSON_PRETTY_PRINT;
    }
    
    $json = json_encode($data, $flags);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new RuntimeException("JSON encode error: " . json_last_error_msg());
    }
    
    return file_put_contents($filename, $json, LOCK_EX) !== false;
}

// JSON configuration manager
class JSONConfig {
    private string $configFile;
    private array $config = [];
    
    public function __construct(string $configFile) {
        $this->configFile = $configFile;
        $this->load();
    }
    
    public function load(): void {
        if (file_exists($this->configFile)) {
            $this->config = readJSONFile($this->configFile);
        }
    }
    
    public function save(): bool {
        return writeJSONFile($this->configFile, $this->config);
    }
    
    public function get(string $key, mixed $default = null): mixed {
        return $this->config[$key] ?? $default;
    }
    
    public function set(string $key, mixed $value): self {
        $this->config[$key] = $value;
        return $this;
    }
    
    public function has(string $key): bool {
        return isset($this->config[$key]);
    }
    
    public function remove(string $key): self {
        unset($this->config[$key]);
        return $this;
    }
    
    public function getAll(): array {
        return $this->config;
    }
}

// Validate JSON structure
function validateJSONStructure(array $data, array $schema): array {
    $errors = [];
    
    foreach ($schema as $field => $rules) {
        if ($rules['required'] ?? false) {
            if (!isset($data[$field])) {
                $errors[] = "Required field missing: $field";
                continue;
            }
        }
        
        if (isset($data[$field])) {
            $value = $data[$field];
            $expectedType = $rules['type'] ?? null;
            
            if ($expectedType && gettype($value) !== $expectedType) {
                $errors[] = "Field '$field' must be of type $expectedType";
            }
            
            if (isset($rules['min_length']) && is_string($value) && strlen($value) < $rules['min_length']) {
                $errors[] = "Field '$field' must be at least {$rules['min_length']} characters";
            }
            
            if (isset($rules['max_length']) && is_string($value) && strlen($value) > $rules['max_length']) {
                $errors[] = "Field '$field' must not exceed {$rules['max_length']} characters";
            }
        }
    }
    
    return $errors;
}

// Process large JSON files efficiently
function processLargeJSONFile(string $filename, callable $processor): array {
    $handle = fopen($filename, 'r');
    if (!$handle) {
        throw new RuntimeException("Cannot open JSON file: $filename");
    }
    
    $buffer = '';
    $stats = ['processed' => 0, 'errors' => 0];
    
    while (!feof($handle)) {
        $chunk = fread($handle, 8192);
        $buffer .= $chunk;
        
        // Try to decode complete JSON objects
        $decoder = json_decode($buffer, true);
        if (json_last_error() === JSON_ERROR_NONE) {
            try {
                $processor($decoder);
                $stats['processed']++;
            } catch (Exception $e) {
                $stats['errors']++;
                error_log("JSON processing error: " . $e->getMessage());
            }
            $buffer = '';
        }
    }
    
    fclose($handle);
    return $stats;
}

// Merge JSON files
function mergeJSONFiles(array $files, string $outputFile): bool {
    $merged = [];
    
    foreach ($files as $file) {
        if (file_exists($file)) {
            $data = readJSONFile($file);
            $merged = array_merge_recursive($merged, $data);
        }
    }
    
    return writeJSONFile($outputFile, $merged);
}

// Convert CSV to JSON
function csvToJSON(string $csvFile, string $jsonFile): bool {
    $csvData = [];
    $handle = fopen($csvFile, 'r');
    
    if (!$handle) {
        return false;
    }
    
    $header = fgetcsv($handle);
    
    while (($row = fgetcsv($handle)) !== false) {
        $csvData[] = array_combine($header, $row);
    }
    
    fclose($handle);
    
    return writeJSONFile($jsonFile, $csvData);
}

// JSON file backup and restore
function backupJSONFile(string $filename): string {
    if (!file_exists($filename)) {
        throw new InvalidArgumentException("File not found: $filename");
    }
    
    $timestamp = date('Y-m-d_H-i-s');
    $backupFile = $filename . '.backup.' . $timestamp;
    
    if (!copy($filename, $backupFile)) {
        throw new RuntimeException("Cannot create backup: $backupFile");
    }
    
    return $backupFile;
}

// Usage examples
try {
    // Basic JSON operations
    $data = [
        'name' => 'My Application',
        'version' => '1.0.0',
        'settings' => [
            'debug' => true,
            'max_users' => 100
        ]
    ];
    
    writeJSONFile('config.json', $data);
    $loadedData = readJSONFile('config.json');
    echo "App name: " . $loadedData['name'] . "\n";
    
    // Configuration management
    $config = new JSONConfig('app_config.json');
    $config->set('database_host', 'localhost')
           ->set('database_port', 3306)
           ->set('cache_enabled', true)
           ->save();
    
    echo "Database host: " . $config->get('database_host') . "\n";
    
    // Validation
    $schema = [
        'name' => ['required' => true, 'type' => 'string', 'min_length' => 1],
        'age' => ['required' => true, 'type' => 'integer'],
        'email' => ['required' => false, 'type' => 'string']
    ];
    
    $userData = ['name' => 'John', 'age' => 25];
    $validationErrors = validateJSONStructure($userData, $schema);
    
    if (empty($validationErrors)) {
        echo "User data is valid\n";
    } else {
        echo "Validation errors: " . implode(', ', $validationErrors) . "\n";
    }
    
    // Merge multiple JSON files
    $configFiles = ['default.json', 'environment.json', 'user.json'];
    mergeJSONFiles($configFiles, 'merged_config.json');
    
    // Convert CSV to JSON
    csvToJSON('users.csv', 'users.json');
    
    // Create backup
    $backupFile = backupJSONFile('important_data.json');
    echo "Backup created: $backupFile\n";
    
} catch (Exception $e) {
    echo "JSON operation error: " . $e->getMessage() . "\n";
}

// Advanced: Stream JSON processing for very large files
function streamJSONArray(string $filename, callable $itemProcessor): void {
    $handle = fopen($filename, 'r');
    if (!$handle) {
        throw new RuntimeException("Cannot open file: $filename");
    }
    
    $buffer = '';
    $depth = 0;
    $inString = false;
    $escaped = false;
    
    while (!feof($handle)) {
        $char = fgetc($handle);
        $buffer .= $char;
        
        if (!$escaped && !$inString) {
            if ($char === '{') $depth++;
            elseif ($char === '}') $depth--;
            
            if ($depth === 0 && strlen(trim($buffer)) > 2) {
                $item = json_decode(trim($buffer), true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    $itemProcessor($item);
                }
                $buffer = '';
            }
        }
        
        if ($char === '"' && !$escaped) $inString = !$inString;
        $escaped = ($char === '\\' && !$escaped);
    }
    
    fclose($handle);
}

Behind the Scenes

PHP's JSON functions provide robust data serialization with automatic type conversion and error reporting. The json_encode() and json_decode() functions handle complex data structures including nested arrays and objects while maintaining data integrity.

Key benefits include human-readable format for configuration files, language-independent data exchange, and efficient parsing performance. The functions support various options for controlling output format, handling Unicode characters, and managing floating-point precision.

For large files, streaming approaches prevent memory exhaustion while maintaining the ability to process structured data incrementally. Perfect for configuration management, API data exchange, and structured data storage applications.

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Php