SP6MI

Krótkofalarstwo & DevOps

PHP – REST API

Poniżej krótki skrypt PHP wystawiający API RESTowe, dzięki któremu możemy ładować dane do zewnętrznej bazy danych.

Przypadek użycia: posiadamy na hostingu bazę danych, która jest dostępna tylko z poziomu localhost, chcąc ładować dowolne dane do tej bazy spoza hostingu, najłatwiejszym rozwiązaniem będzie API RESTowe, które możemy odpytywać i metodą PUSH wysyłać dane.

Dane które będziemy przesyłać będą w postaci CSV, skrypt przyjmuje również sekwencję danych csv, separatorem jest znak nowej linii.

API w dość prosty sposób zabezpieczone tokenem, dla uproszczenia implementacji jest on hardcoded.

import.php

<?php
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");

// Database configuration
$dbHost = 'localhost';
$dbName = 'nazwaBazy';
$dbUser = 'uzytkownikBazy';
$dbPass = 'hasloUzytkownika';
$token =  "unikalnyToken";

try {
    $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName", $dbUser, $dbPass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
    exit();
}

// Handle POST request
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['HTTP_X_API_KEY'] === $token) {
    try {
        // Get the raw CSV data from the request body
        $csvData = file_get_contents('php://input');
        
        if (empty($csvData)) {
            http_response_code(400);
            echo json_encode(['error' => 'No CSV data provided']);
            exit();
        }

        // Convert the CSV string into lines
        $lines = explode("\n", trim($csvData));
        
        // Start transaction for batch insert
        $pdo->beginTransaction();
        
        $rowCount = 0;
        $successCount = 0;
        
        // Process each line
        foreach ($lines as $line) {
            $rowCount++;
            
            // Skip empty lines
            if (empty(trim($line))) continue;
            
            // Parse CSV line (handle quoted values)
            $data = str_getcsv($line);
            
            // Validate data (expecting name, email, phone columns)
            if (count($data) < 3) {
                error_log("Skipping row $rowCount: Insufficient data");
                continue;
            }
            
            $name = strtoupper(trim($data[0]));
            $email = trim($data[1]);
            $phone = strtoupper(trim($data[2]));

            // Basic validation
            if (empty($name)) {
                error_log("Skipping row $rowCount: Invalid data - Name: $name, Email: $email, Phone: $phone");
                continue;
            }
            
            // Prepare SQL statement
            $sql = "INSERT INTO tabela (name, email, phone) VALUES (:name, :email, :phone)";
            $stmt = $pdo->prepare($sql);

            try {
                $stmt->execute(['name' => $name, 'email' => $email, 'phone' => $phone]);
                $successCount++;
            } catch (PDOException $e) {
                error_log("Failed to insert row $rowCount: " . $e->getMessage());
            }
        }
        
        // Commit transaction
        $pdo->commit();
        
        // Return success response
        echo json_encode([
            'message' => 'CSV data processed successfully',
            'total_rows' => $rowCount,
            'inserted_rows' => $successCount,
            'skipped_rows' => $rowCount - $successCount
        ]);
        
    } catch (Exception $e) {
        // Rollback transaction on error
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        
        http_response_code(500);
        echo json_encode(['error' => 'Processing failed: ' . $e->getMessage()]);
    }
} else {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
}

// Close database connection
$pdo = null;
?>

Samo zapytanie przyjmie postać:

curl -X POST -H "Content-Type: text/csv" -H "x-api-key: unikalnyToken" --data "Jan,jk@kj.pl,123456789" <urlhostinguzbaza>/import.php