{"id":134,"date":"2025-06-11T18:42:54","date_gmt":"2025-06-11T18:42:54","guid":{"rendered":"https:\/\/sp6mi.pl\/?p=134"},"modified":"2025-06-11T18:44:48","modified_gmt":"2025-06-11T18:44:48","slug":"php-rest-api","status":"publish","type":"post","link":"https:\/\/sp6mi.pl\/index.php\/2025\/06\/11\/php-rest-api\/","title":{"rendered":"PHP &#8211; REST API"},"content":{"rendered":"\n<p>Poni\u017cej kr\u00f3tki skrypt PHP wystawiaj\u0105cy API RESTowe, dzi\u0119ki kt\u00f3remu mo\u017cemy \u0142adowa\u0107 dane do zewn\u0119trznej bazy danych. <\/p>\n\n\n\n<p>Przypadek u\u017cycia: posiadamy na hostingu baz\u0119 danych, kt\u00f3ra jest dost\u0119pna tylko z poziomu <em>localhost<\/em>, chc\u0105c \u0142adowa\u0107 dowolne dane do tej bazy spoza hostingu, naj\u0142atwiejszym rozwi\u0105zaniem b\u0119dzie API RESTowe, kt\u00f3re mo\u017cemy odpytywa\u0107 i metod\u0105 PUSH wysy\u0142a\u0107 dane.<\/p>\n\n\n\n<p>Dane kt\u00f3re b\u0119dziemy przesy\u0142a\u0107 b\u0119d\u0105 w postaci CSV, skrypt przyjmuje r\u00f3wnie\u017c sekwencj\u0119 danych csv, separatorem jest znak nowej linii.<\/p>\n\n\n\n<p>API w do\u015b\u0107 prosty spos\u00f3b zabezpieczone tokenem, dla uproszczenia implementacji jest on hardcoded.<\/p>\n\n\n\n<p>import.php<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nheader(\"Content-Type: application\/json\");\nheader(\"Access-Control-Allow-Origin: *\");\nheader(\"Access-Control-Allow-Methods: POST\");\nheader(\"Access-Control-Allow-Headers: Content-Type\");\n\n\/\/ Database configuration\n$dbHost = 'localhost';\n$dbName = 'nazwaBazy';\n$dbUser = 'uzytkownikBazy';\n$dbPass = 'hasloUzytkownika';\n$token =  \"unikalnyToken\";\n\ntry {\n    $pdo = new PDO(\"mysql:host=$dbHost;dbname=$dbName\", $dbUser, $dbPass);\n    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n} catch (PDOException $e) {\n    http_response_code(500);\n    echo json_encode(&#91;'error' => 'Database connection failed: ' . $e->getMessage()]);\n    exit();\n}\n\n\/\/ Handle POST request\nif ($_SERVER&#91;'REQUEST_METHOD'] === 'POST' &amp;&amp; $_SERVER&#91;'HTTP_X_API_KEY'] === $token) {\n    try {\n        \/\/ Get the raw CSV data from the request body\n        $csvData = file_get_contents('php:\/\/input');\n        \n        if (empty($csvData)) {\n            http_response_code(400);\n            echo json_encode(&#91;'error' => 'No CSV data provided']);\n            exit();\n        }\n\n        \/\/ Convert the CSV string into lines\n        $lines = explode(\"\\n\", trim($csvData));\n        \n        \/\/ Start transaction for batch insert\n        $pdo->beginTransaction();\n        \n        $rowCount = 0;\n        $successCount = 0;\n        \n        \/\/ Process each line\n        foreach ($lines as $line) {\n            $rowCount++;\n            \n            \/\/ Skip empty lines\n            if (empty(trim($line))) continue;\n            \n            \/\/ Parse CSV line (handle quoted values)\n            $data = str_getcsv($line);\n            \n            \/\/ Validate data (expecting name, email, phone columns)\n            if (count($data) &lt; 3) {\n                error_log(\"Skipping row $rowCount: Insufficient data\");\n                continue;\n            }\n            \n            $name = strtoupper(trim($data&#91;0]));\n            $email = trim($data&#91;1]);\n            $phone = strtoupper(trim($data&#91;2]));\n\n            \/\/ Basic validation\n            if (empty($name)) {\n                error_log(\"Skipping row $rowCount: Invalid data - Name: $name, Email: $email, Phone: $phone\");\n                continue;\n            }\n            \n            \/\/ Prepare SQL statement\n            $sql = \"INSERT INTO tabela (name, email, phone) VALUES (:name, :email, :phone)\";\n            $stmt = $pdo->prepare($sql);\n\n            try {\n                $stmt->execute(&#91;'name' => $name, 'email' => $email, 'phone' => $phone]);\n                $successCount++;\n            } catch (PDOException $e) {\n                error_log(\"Failed to insert row $rowCount: \" . $e->getMessage());\n            }\n        }\n        \n        \/\/ Commit transaction\n        $pdo->commit();\n        \n        \/\/ Return success response\n        echo json_encode(&#91;\n            'message' => 'CSV data processed successfully',\n            'total_rows' => $rowCount,\n            'inserted_rows' => $successCount,\n            'skipped_rows' => $rowCount - $successCount\n        ]);\n        \n    } catch (Exception $e) {\n        \/\/ Rollback transaction on error\n        if ($pdo->inTransaction()) {\n            $pdo->rollBack();\n        }\n        \n        http_response_code(500);\n        echo json_encode(&#91;'error' => 'Processing failed: ' . $e->getMessage()]);\n    }\n} else {\n    http_response_code(405);\n    echo json_encode(&#91;'error' => 'Method not allowed']);\n}\n\n\/\/ Close database connection\n$pdo = null;\n?>\n<\/code><\/pre>\n\n\n\n<p>Samo zapytanie przyjmie posta\u0107: <\/p>\n\n\n\n<p><code>curl -X POST -H \"Content-Type: text\/csv\" -H \"x-api-key: unikalnyToken\" --data \"Jan,jk@kj.pl,123456789\" &lt;urlhostinguzbaza>\/import.php<\/code><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Poni\u017cej kr\u00f3tki skrypt PHP wystawiaj\u0105cy API RESTowe, dzi\u0119ki kt\u00f3remu mo\u017cemy \u0142adowa\u0107 dane do zewn\u0119trznej bazy danych. Przypadek u\u017cycia: posiadamy na hostingu baz\u0119 danych, kt\u00f3ra jest dost\u0119pna tylko z poziomu localhost, chc\u0105c \u0142adowa\u0107 dowolne dane do tej bazy spoza hostingu, naj\u0142atwiejszym rozwi\u0105zaniem b\u0119dzie API RESTowe, kt\u00f3re mo\u017cemy odpytywa\u0107 i metod\u0105 PUSH wysy\u0142a\u0107 dane. Dane kt\u00f3re b\u0119dziemy&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[11],"tags":[16,15],"class_list":["post-134","post","type-post","status-publish","format-standard","hentry","category-devops","tag-coding","tag-php"],"_links":{"self":[{"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/comments?post=134"}],"version-history":[{"count":4,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/posts\/134\/revisions"}],"predecessor-version":[{"id":138,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/posts\/134\/revisions\/138"}],"wp:attachment":[{"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/media?parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/categories?post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sp6mi.pl\/index.php\/wp-json\/wp\/v2\/tags?post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}