Skip to content

Commit 0d69f01

Browse files
authored
init
1 parent d0c3ba0 commit 0d69f01

File tree

12 files changed

+417
-0
lines changed

12 files changed

+417
-0
lines changed

app/Application.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use App\Http\Request;
6+
use App\Routing\Route;
7+
8+
class Application
9+
{
10+
public function __construct()
11+
{
12+
$this->request = Request::url();
13+
$this->route = new Route($this->request->method, $this->request->path);
14+
}
15+
16+
public function run()
17+
{
18+
$this->route->call();
19+
}
20+
}

app/Controllers/Controller.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace App\Controllers;
4+
5+
class Controller
6+
{
7+
//
8+
}

app/Controllers/UserController.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace App\Controllers;
4+
5+
use App\Http\Request;
6+
use App\Http\Response;
7+
use App\Models\Users;
8+
9+
class UserController extends Controller
10+
{
11+
/**
12+
* Display a listing of the resource.
13+
*
14+
* @return \Http\Request
15+
*/
16+
public function index(Request $request)
17+
{
18+
$users = Users::all();
19+
Response::json($users);
20+
}
21+
22+
/**
23+
* Store a newly created resource in storage.
24+
*
25+
* @param \Http\Request $request
26+
*/
27+
public function store(Request $request)
28+
{
29+
Users::create($request->json());
30+
}
31+
32+
/**
33+
* Display the specified resource.
34+
*
35+
* @param \Http\Request $request
36+
*/
37+
public function show(Request $request)
38+
{
39+
$user = Users::find($request->params->id);
40+
Response::json($user);
41+
}
42+
43+
/**
44+
* Update the specified resource in storage.
45+
*
46+
* @param \Http\Request $request
47+
*/
48+
public function update(Request $request)
49+
{
50+
Users::update($request->input(), $request->params->id);
51+
}
52+
53+
/**
54+
* Remove the specified resource from storage.
55+
*
56+
* @param \Http\Request $request
57+
*/
58+
public function destroy(Request $request)
59+
{
60+
Users::delete($request->params->id);
61+
}
62+
}

app/Http/Request.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App\Http;
4+
5+
class Request
6+
{
7+
public $params;
8+
public $query;
9+
public $contentType;
10+
public $method;
11+
public $path;
12+
13+
public function __construct($args)
14+
{
15+
$this->params = $args->params;
16+
$this->query = $args->query;
17+
$this->contentType = $_SERVER["CONTENT_TYPE"] ?? '';
18+
$this->method = $_SERVER["REQUEST_METHOD"];
19+
$this->path = $_SERVER["REQUEST_URI"];
20+
}
21+
22+
public static function url()
23+
{
24+
return (object)["method" => $_SERVER["REQUEST_METHOD"], "path" => $_SERVER["REQUEST_URI"]];
25+
}
26+
27+
public function json()
28+
{
29+
if ($this->method !== "POST" || $this->contentType !== "application/json") {
30+
return [];
31+
}
32+
return json_decode(trim(file_get_contents("php://input")));
33+
}
34+
35+
public function input()
36+
{
37+
if ($this->method === "PUT") {
38+
parse_str(file_get_contents("php://input"), $body);
39+
return (object)$body;
40+
}
41+
42+
if ($this->method !== "POST") {
43+
return [];
44+
}
45+
46+
$body = [];
47+
foreach ($_POST as $key => $value) {
48+
$body[$key] = filter_input(INPUT_POST, $key, FILTER_SANITIZE_SPECIAL_CHARS);
49+
}
50+
return (object)$body;
51+
}
52+
}

app/Http/Response.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace App\Http;
4+
5+
class Response
6+
{
7+
public static function json($body)
8+
{
9+
header('Content-Type: application/json');
10+
exit(json_encode($body));
11+
}
12+
13+
public static function make($code, $type, $message)
14+
{
15+
return [
16+
"code" => $code,
17+
"type" => $type,
18+
"message" => $message
19+
];
20+
}
21+
22+
23+
public static function _404()
24+
{
25+
http_response_code(404);
26+
$resposne = [
27+
"code" => 404,
28+
"type" => "404 Not Found",
29+
"message" => "The requested resource could not be found but may be available again in the future."
30+
];
31+
return self::json($resposne);
32+
}
33+
}

app/Models/Database.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use PDO;
6+
7+
class Database
8+
{
9+
private static $dbh = null;
10+
11+
public static function connect()
12+
{
13+
if (is_null(self::$dbh)) {
14+
self::$dbh = new PDO($_ENV["DSN"], $_ENV["USERNAME"], $_ENV["PASSWORD"]);
15+
self::$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
16+
}
17+
return self::$dbh;
18+
}
19+
}

app/Models/Model.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
class Model
6+
{
7+
8+
public function __construct()
9+
{
10+
//
11+
}
12+
13+
public static function all()
14+
{
15+
$table = substr(strrchr(get_called_class(), "\\"), 1);;
16+
$dbh = Database::connect();
17+
$sth = $dbh->prepare("SELECT * FROM $table;");
18+
$sth->execute();
19+
return $sth->fetchAll();
20+
}
21+
22+
public static function create(object $qq)
23+
{
24+
$dbh = Database::connect();
25+
$table = substr(strrchr(get_called_class(), "\\"), 1);
26+
27+
$columns = implode(',', array_keys((array)$qq));
28+
$values = implode(',', array_map(function ($val) {
29+
return is_string($val) ? "'$val'" : $val;
30+
}, array_values((array)$qq)));
31+
$query = "INSERT INTO $table ($columns) VALUES ($values);";
32+
print_r($query);
33+
exit;
34+
$sth = $dbh->prepare($query);
35+
$sth->execute();
36+
}
37+
38+
public static function delete(int $id)
39+
{
40+
$table = substr(strrchr(get_called_class(), "\\"), 1);
41+
$dbh = Database::connect();
42+
$dbh->prepare("DELETE FROM $table where id = ?;")->execute([$id]);
43+
}
44+
45+
public static function find(int $id)
46+
{
47+
$table = substr(strrchr(get_called_class(), "\\"), 1);
48+
$dbh = Database::connect();
49+
$sth = $dbh->prepare("SELECT * FROM $table WHERE id = ?;");
50+
$sth->execute([$id]);
51+
return $sth->fetchAll();
52+
}
53+
54+
public static function update(object $qq, int $id)
55+
{
56+
$table = substr(strrchr(get_called_class(), "\\"), 1);
57+
$dbh = Database::connect();
58+
$value = (array) ($qq);
59+
60+
$values = implode(',', array_map(
61+
function ($v, $k) {
62+
$v = is_numeric($v) ? (int)$v : "'$v'";
63+
return "$k=$v";
64+
},
65+
$value,
66+
array_keys($value)
67+
));
68+
69+
$query = "UPDATE $table SET $values WHERE id = $id;";
70+
$sth = $dbh->prepare($query);
71+
$sth->execute();
72+
}
73+
}

app/Models/Users.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
class Users extends Model
6+
{
7+
public function __construct()
8+
{
9+
//
10+
}
11+
}

app/Routing/Route.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace App\Routing;
4+
5+
use App\Http\Request;
6+
use App\Http\Response;
7+
8+
class Route
9+
{
10+
private static $routes = [];
11+
private $matches_route = null;
12+
private $wildcard = '/\{(.*?)\}/';
13+
private $parameters = [];
14+
private $query = [];
15+
16+
public function __construct($method, $path)
17+
{
18+
$this->method = $method;
19+
$this->path = $path;
20+
}
21+
22+
public static function get($uri, $fn)
23+
{
24+
self::make("GET", $uri, $fn);
25+
}
26+
27+
public static function post($uri, $fn)
28+
{
29+
self::make("POST", $uri, $fn);
30+
}
31+
32+
public static function put($uri, $fn)
33+
{
34+
self::make("PUT", $uri, $fn);
35+
}
36+
37+
public static function delete($uri, $fn)
38+
{
39+
self::make("DELETE", $uri, $fn);
40+
}
41+
42+
public function call()
43+
{
44+
$routes = $this->filter_routes_by_method(self::$routes, $this->method) ?: Response::_404();
45+
46+
foreach ($routes as $value) {
47+
if ($this->matche($value["pattern"], $this->path) === true) {
48+
$this->matches_route = (object) $value;
49+
break 1;
50+
}
51+
}
52+
53+
$this->matches_route ?: Response::_404();
54+
55+
$callback = $this->matches_route->callback;
56+
$arg = (object)["params" => (object) $this->parameters, "query" => (object) $this->query];
57+
return call_user_func($callback, (new Request($arg)));
58+
}
59+
60+
public static function make($method, $pattern, $callback)
61+
{
62+
$action = ["method" => $method, "pattern" => $pattern, "callback" => $callback];
63+
array_push(self::$routes, $action);
64+
}
65+
66+
protected function filter_routes_by_method(array $routes, string $method)
67+
{
68+
$_ = [];
69+
foreach ($routes as $value) {
70+
if ($value["method"] === $method) {
71+
array_push($_, $value);
72+
}
73+
}
74+
return $_;
75+
}
76+
77+
public function matche($pattern, $path)
78+
{
79+
$url = parse_url($path);
80+
$path = $url["path"];
81+
parse_str($url["query"] ?? '', $this->query);
82+
83+
$parameters = preg_replace_callback($this->wildcard, function ($m) {
84+
return '(?<' . preg_replace($this->wildcard, '$1', $m[0]) . '>[a-zA-Z0-9_\-\@\.]+)';
85+
}, $pattern);
86+
87+
$parameters = ('@^' . $parameters . '$@');
88+
89+
if (preg_match($parameters, $path, $params)) {
90+
foreach ($params as $key => $value) {
91+
if (is_string($key)) {
92+
$this->parameters[$key] = $value;
93+
}
94+
}
95+
return true;
96+
}
97+
return false;
98+
}
99+
}

0 commit comments

Comments
 (0)