Skip to content

Instantly share code, notes, and snippets.

@stevenpray
Created December 15, 2017 11:35
Show Gist options
  • Save stevenpray/b46e3e62effe4b440823f39de2b8a889 to your computer and use it in GitHub Desktop.
Save stevenpray/b46e3e62effe4b440823f39de2b8a889 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
ini_set('html_errors', 'false');
error_reporting(E_ALL | E_STRICT);
set_exception_handler('error');
define('DB_HOST', '127.0.0.1');
define('DB_USER', 'root');
define('DB_PASS', null);
define('DB_NAME', 'untitled');
/**
* Response handler.
*
* @param int $status
* @param mixed $data
*/
function respond(int $status, $data = null): void
{
http_response_code($status);
header('Content-Type: application/json');
if ($data !== null) {
echo json_encode($data, JSON_PRETTY_PRINT);
}
die;
}
/**
* Catch-all error handler.
*
* @param Throwable $throwable
*/
function error(Throwable $throwable): void
{
respond(500, $throwable->getMessage());
}
$pdo = new PDO(
sprintf('mysql:host=%s;dbname=%s', DB_HOST, DB_NAME),
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
/**
* Fetch company entity with embedded company_addresses.
*
* @param PDO $pdo
* @param int $id
* @return array
*/
function fetch_company(PDO $pdo, int $id = null): array
{
$sql = 'SELECT * FROM company';
if ($id !== null) {
$sql = 'SELECT * FROM company WHERE company.id = :id';
}
$statement = $pdo->prepare($sql);
$statement->bindParam(':id', $id, PDO::PARAM_INT);
$statement->execute();
$result = [];
while ($row = $statement->fetch()) {
$sql = 'SELECT * FROM company_address WHERE company_address.company_id = :id';
$statement2 = $pdo->prepare($sql);
$statement2->bindParam(':id', $row['id'], PDO::PARAM_INT);
$statement2->execute();
$row['addresses'] = $statement2->fetchAll();
$result[] = $row;
}
return $result;
}
// Parse request body.
$data = json_decode(file_get_contents('php://input'), true);
// Controllers.
$routes = [
'/^\/$/' => [
'GET' => function () use ($pdo) {
respond(200, fetch_company($pdo));
},
'POST' => function () use ($pdo, $data) {
$sql = 'INSERT INTO company (name, description) VALUES (:name, :description)';
$statement = $pdo->prepare($sql);
$statement->bindParam(':name', $data['name']);
$statement->bindParam(':description', $data['description']);
$statement->execute();
$id = (int)$pdo->lastInsertId();
$sql = 'INSERT INTO company_address (company_id, address, address_2, city, state, zip) VALUES (:company_id, :address, :address_2, :city, :state, :zip)';
$statement = $pdo->prepare($sql);
$statement->bindParam(':company_id', $id, PDO::PARAM_INT);
$statement->bindParam(':address', $data['address']);
$statement->bindParam(':address_2', $data['address_2']);
$statement->bindParam(':city', $data['city']);
$statement->bindParam(':state', $data['state']);
$statement->bindParam(':zip', $data['zip']);
$statement->execute();
$pdo->commit();
respond(201, fetch_company($pdo, $id));
},
],
'/^\/[0-9]+$/' => [
'GET' => function (int $id) use ($pdo) {
respond(200, fetch_company($pdo, $id));
},
'DELETE' => function (int $id) use ($pdo) {
$statement = $pdo->prepare('DELETE FROM company WHERE id = :id');
$statement->bindParam(':id', $id, PDO::PARAM_INT);
$statement->execute();
$pdo->commit();
respond(200, 'Deleted.');
},
'PUT' => function (int $id) use ($pdo, $data) {
$table_fields = [
'company' => ['name', 'description'],
'company_address' => ['address', 'address_2', 'city', 'state', 'zip'],
];
$params = [];
/** @var string[] $fields */
foreach ($table_fields as $table => $fields) {
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
$params[$field] = sprintf('%1$s.%2$s = :%2$s', $table, $field);
}
}
}
$sql = sprintf('UPDATE company LEFT JOIN company_address ON (company.id = company_address.company_id) SET %s WHERE (company.id = :id)', implode(', ', $params));
$statement = $pdo->prepare($sql);
foreach ($params as $field => $param) {
$statement->bindParam(':'.$field, $data[$field]);
}
$statement->bindParam(':id', $id, PDO::PARAM_INT);
$statement->execute();
$pdo->commit();
respond(200, fetch_company($pdo, $id));
},
],
];
// Router.
//['REQUEST_URI' => $uri, 'REQUEST_METHOD' => $method] = $_SERVER
/** @var callable[] $route */
foreach ($routes as $uri => $route) {
if (preg_match($uri, $_SERVER['REQUEST_URI'], $matches)) {
foreach ($route as $method => $controller) {
if ($method === $_SERVER['REQUEST_METHOD']) {
$id = null;
if (count($matches) > 1) {
$id = (int)ltrim(array_shift($matches), '/');
}
if ($id) {
$sql = 'SELECT id FROM company WHERE id = :id';
$statement = $pdo->prepare($sql);
$statement->bindParam(':id', $id);
$statement->execute();
if ($statement->fetch() === false) {
respond(404);
}
}
try {
$pdo->beginTransaction();
$controller($id);
} catch (PDOException $exception) {
$pdo->rollBack();
if ($exception->getCode() === '23000') {
respond(422, $exception->getMessage());
}
throw $exception;
}
}
}
respond(405);
}
}
respond(404);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment