{"id":135,"date":"2025-01-05T02:11:47","date_gmt":"2025-01-05T01:11:47","guid":{"rendered":"https:\/\/josefnemec.cz\/blog\/?p=135"},"modified":"2025-01-05T02:11:47","modified_gmt":"2025-01-05T01:11:47","slug":"jak-vytvorit-rest-api-v-php-8-3","status":"publish","type":"post","link":"https:\/\/josefnemec.cz\/blog\/php\/jak-vytvorit-rest-api-v-php-8-3\/","title":{"rendered":"Jak vytvo\u0159it REST API v PHP 8.3"},"content":{"rendered":"\n<p>V tomto \u010dl\u00e1nku si uk\u00e1\u017eeme, jak vytvo\u0159it jednoduch\u00e9 REST API v PHP 8.3, kter\u00e9 umo\u017en\u00ed prov\u00e1d\u011bt CRUD operace (Create, Read, Update, Delete) nad seznamem polo\u017eek. Pou\u017eijeme \u010dist\u00fd PHP k\u00f3d bez framework\u016f, abychom co nejv\u00edce pochopili, jak REST API funguje.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">1. Nastaven\u00ed projektu<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Vytvo\u0159te slo\u017eku pro projekt: <code>mkdir php-rest-api cd php-rest-api<\/code><\/li>\n\n\n\n<li>Vytvo\u0159te soubor <code>index.php<\/code>, kter\u00fd bude slou\u017eit jako vstupn\u00ed bod API.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">2. Datov\u00e1 struktura<\/h4>\n\n\n\n<p>Pro jednoduchost budeme data uchov\u00e1vat v souboru <code>data.json<\/code>. Tento soubor bude obsahovat seznam polo\u017eek ve form\u00e1tu JSON.<\/p>\n\n\n\n<p><strong>data.json:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;\n    {\"id\": 1, \"name\": \"Polo\u017eka 1\", \"description\": \"Popis polo\u017eky 1\"},\n    {\"id\": 2, \"name\": \"Polo\u017eka 2\", \"description\": \"Popis polo\u017eky 2\"}\n]\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">3. Implementace REST API<\/h4>\n\n\n\n<p>Otev\u0159ete soubor <code>index.php<\/code> a napi\u0161te n\u00e1sleduj\u00edc\u00ed k\u00f3d.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nheader(\"Content-Type: application\/json\");\n\n\/\/ Na\u010d\u00edt\u00e1n\u00ed dat ze souboru\nfunction loadData(): array {\n    $data = file_get_contents('data.json');\n    return json_decode($data, true);\n}\n\n\/\/ Ukl\u00e1d\u00e1n\u00ed dat do souboru\nfunction saveData(array $data): void {\n    file_put_contents('data.json', json_encode($data, JSON_PRETTY_PRINT));\n}\n\n\/\/ Zji\u0161t\u011bn\u00ed HTTP metody a cesty\n$method = $_SERVER&#91;'REQUEST_METHOD'];\n$path = trim($_SERVER&#91;'PATH_INFO'] ?? '\/', '\/');\n\n\/\/ Rozd\u011blen\u00ed cesty na segmenty\n$segments = explode('\/', $path);\n\n$data = loadData();\n\n\/\/ Funkce pro odpov\u011bdi\nfunction respond($status, $response) {\n    http_response_code($status);\n    echo json_encode($response);\n    exit;\n}\n\n\/\/ Route handling\nif ($segments&#91;0] === 'items') {\n    \/\/ GET \/items - seznam polo\u017eek\n    if ($method === 'GET' &amp;&amp; count($segments) === 1) {\n        respond(200, $data);\n    }\n\n    \/\/ GET \/items\/{id} - detail polo\u017eky\n    if ($method === 'GET' &amp;&amp; count($segments) === 2) {\n        $id = (int) $segments&#91;1];\n        foreach ($data as $item) {\n            if ($item&#91;'id'] === $id) {\n                respond(200, $item);\n            }\n        }\n        respond(404, &#91;\"message\" =&gt; \"Polo\u017eka nenalezena\"]);\n    }\n\n    \/\/ POST \/items - vytvo\u0159en\u00ed polo\u017eky\n    if ($method === 'POST' &amp;&amp; count($segments) === 1) {\n        $input = json_decode(file_get_contents('php:\/\/input'), true);\n        if (!isset($input&#91;'name']) || !isset($input&#91;'description'])) {\n            respond(400, &#91;\"message\" =&gt; \"Neplatn\u00e1 data\"]);\n        }\n\n        $newItem = &#91;\n            \"id\" =&gt; end($data)&#91;'id'] + 1,\n            \"name\" =&gt; $input&#91;'name'],\n            \"description\" =&gt; $input&#91;'description']\n        ];\n\n        $data&#91;] = $newItem;\n        saveData($data);\n\n        respond(201, $newItem);\n    }\n\n    \/\/ PUT \/items\/{id} - aktualizace polo\u017eky\n    if ($method === 'PUT' &amp;&amp; count($segments) === 2) {\n        $id = (int) $segments&#91;1];\n        $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n        foreach ($data as &amp;$item) {\n            if ($item&#91;'id'] === $id) {\n                $item&#91;'name'] = $input&#91;'name'] ?? $item&#91;'name'];\n                $item&#91;'description'] = $input&#91;'description'] ?? $item&#91;'description'];\n\n                saveData($data);\n                respond(200, $item);\n            }\n        }\n        respond(404, &#91;\"message\" =&gt; \"Polo\u017eka nenalezena\"]);\n    }\n\n    \/\/ DELETE \/items\/{id} - smaz\u00e1n\u00ed polo\u017eky\n    if ($method === 'DELETE' &amp;&amp; count($segments) === 2) {\n        $id = (int) $segments&#91;1];\n        foreach ($data as $index =&gt; $item) {\n            if ($item&#91;'id'] === $id) {\n                array_splice($data, $index, 1);\n                saveData($data);\n                respond(204, null);\n            }\n        }\n        respond(404, &#91;\"message\" =&gt; \"Polo\u017eka nenalezena\"]);\n    }\n}\n\n\/\/ Nezn\u00e1m\u00e1 cesta\nrespond(404, &#91;\"message\" =&gt; \"Neplatn\u00e1 cesta\"]);\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">4. Testov\u00e1n\u00ed API<\/h4>\n\n\n\n<p>M\u016f\u017eete API testovat pomoc\u00ed n\u00e1stroj\u016f jako Postman nebo curl:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Z\u00edsk\u00e1n\u00ed seznamu polo\u017eek:<\/strong> <code>curl -X GET http:\/\/localhost\/items<\/code><\/li>\n\n\n\n<li><strong>Vytvo\u0159en\u00ed polo\u017eky:<\/strong> <code>curl -X POST http:\/\/localhost\/items -H \"Content-Type: application\/json\" -d '{\"name\": \"Polo\u017eka 3\", \"description\": \"Popis polo\u017eky 3\"}'<\/code><\/li>\n\n\n\n<li><strong>Aktualizace polo\u017eky:<\/strong> <code>curl -X PUT http:\/\/localhost\/items\/1 -H \"Content-Type: application\/json\" -d '{\"name\": \"Nov\u00e1 polo\u017eka 1\"}'<\/code><\/li>\n\n\n\n<li><strong>Smaz\u00e1n\u00ed polo\u017eky:<\/strong> <code>curl -X DELETE http:\/\/localhost\/items\/1<\/code><\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Z\u00e1v\u011br<\/h4>\n\n\n\n<p>Tento \u010dl\u00e1nek ukazuje z\u00e1kladn\u00ed principy REST API v PHP. Pro produk\u010dn\u00ed nasazen\u00ed by bylo vhodn\u00e9 pou\u017e\u00edt framework (nap\u0159. Laravel nebo Nette) a datab\u00e1zi pro uklad\u00e1n\u00ed dat.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>V tomto \u010dl\u00e1nku si uk\u00e1\u017eeme, jak vytvo\u0159it jednoduch\u00e9 REST API v PHP 8.3, kter\u00e9 umo\u017en\u00ed prov\u00e1d\u011bt CRUD operace (Create, Read, Update, Delete) nad seznamem polo\u017eek. Pou\u017eijeme \u010dist\u00fd PHP k\u00f3d bez framework\u016f, abychom co nejv\u00edce pochopili, jak REST API funguje. 1.<\/p>\n","protected":false},"author":1,"featured_media":136,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,77],"tags":[81,47,10,49,82],"class_list":["post-135","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php","category-technologie","tag-api","tag-php","tag-php8","tag-programovani","tag-rest"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/josefnemec.cz\/blog\/wp-content\/uploads\/2025\/01\/DALL%C2%B7E-2025-01-05-02.09.46-A-visually-appealing-illustration-of-a-REST-API-concept-in-PHP-8.3.-The-image-features-a-sleek-and-modern-design-of-interconnected-blocks-representing.webp?fit=1024%2C1024&ssl=1","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/posts\/135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/comments?post=135"}],"version-history":[{"count":1,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions"}],"predecessor-version":[{"id":137,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions\/137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/media\/136"}],"wp:attachment":[{"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/media?parent=135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/categories?post=135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/josefnemec.cz\/blog\/wp-json\/wp\/v2\/tags?post=135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}