PHP uses http_response_code() to set status codes. Like header(), it must be called before any output:
CORS in PHP
Cross-origin requests require specific headers. In PHP, set them with header():
The browser sends an OPTIONS preflight request before any non-simple request (PUT, DELETE, or requests with custom headers). Your API must respond to it with the appropriate CORS headers.
Testing with curl
# GET all items
curl https://cse135.site/php-tutorial/05-rest-api/api.php/items
# GET one item
curl https://cse135.site/php-tutorial/05-rest-api/api.php/items/1
# POST - Create item
curl -X POST https://cse135.site/php-tutorial/05-rest-api/api.php/items \
-H "Content-Type: application/json" \
-d '{"name": "Learn REST"}'
# PUT - Update item
curl -X PUT https://cse135.site/php-tutorial/05-rest-api/api.php/items/1 \
-H "Content-Type: application/json" \
-d '{"name": "Updated Item", "completed": true}'
# DELETE - Remove item
curl -X DELETE https://cse135.site/php-tutorial/05-rest-api/api.php/items/1
Comparison with Node.js
Aspect
PHP (this tutorial)
Node.js (Express)
Routing
Manual (PATH_INFO + switch)
Built-in (app.get(), app.post())
JSON body
file_get_contents('php://input')
req.body (with middleware)
Storage
JSON file (must persist externally)
In-memory array (process persists)
Status codes
http_response_code(201)
res.status(201)
Response
echo json_encode($data)
res.json(data)
URL params
Parse $_SERVER['PATH_INFO']
req.params.id
Deployment
Drop files in Apache docroot
Run node server.js + process manager
Summary
PHP REST APIs run inside Apache, using .htaccess for URL rewriting and PATH_INFO for routing
Manual routing reads REQUEST_METHOD and PATH_INFO from $_SERVER
JSON request bodies require file_get_contents('php://input') and json_decode()
Use http_response_code() for status codes and header() for CORS
PHP needs external storage (files, database) because each request starts fresh