├── .gitignore ├── .github ├── api.png ├── miniatura-v2.png └── screenshot.png ├── api ├── composer.json ├── .htaccess ├── index.php ├── src │ ├── Controllers │ │ ├── HomeController.php │ │ ├── NotFoundController.php │ │ └── UserController.php │ ├── Models │ │ ├── Database.php │ │ └── User.php │ ├── Http │ │ ├── Response.php │ │ ├── Request.php │ │ ├── Route.php │ │ └── JWT.php │ ├── Utils │ │ └── Validator.php │ ├── routes │ │ └── main.php │ ├── Core │ │ └── Core.php │ └── Services │ │ └── UserService.php └── composer.lock ├── LICENSE └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ -------------------------------------------------------------------------------- /.github/api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricNeves/yt-api-com-php/HEAD/.github/api.png -------------------------------------------------------------------------------- /.github/miniatura-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricNeves/yt-api-com-php/HEAD/.github/miniatura-v2.png -------------------------------------------------------------------------------- /.github/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricNeves/yt-api-com-php/HEAD/.github/screenshot.png -------------------------------------------------------------------------------- /api/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoload": { 3 | "psr-4": { 4 | "App\\": "src/" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /api/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | 3 | RewriteCond %{REQUEST_FILENAME} !-d 4 | RewriteCond %{REQUEST_FILENAME} !-f 5 | 6 | RewriteRule ^(.*)$ index.php?url=$1 [QSA] -------------------------------------------------------------------------------- /api/index.php: -------------------------------------------------------------------------------- 1 | $value) { 10 | if (empty(trim($value))) { 11 | throw new \Exception("The field ($field) is required."); 12 | } 13 | } 14 | 15 | return $fields; 16 | } 17 | } -------------------------------------------------------------------------------- /api/src/routes/main.php: -------------------------------------------------------------------------------- 1 | true, 14 | 'success' => false, 15 | 'message' => 'Sorry, route not found.' 16 | ], 404); 17 | return; 18 | } 19 | } -------------------------------------------------------------------------------- /api/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "d751713988987e9331980363e24189ce", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": [], 16 | "platform-dev": [], 17 | "plugin-api-version": "2.2.0" 18 | } 19 | -------------------------------------------------------------------------------- /api/src/Http/Request.php: -------------------------------------------------------------------------------- 1 | $_GET, 18 | 'POST', 'PUT', 'DELETE' => $json, 19 | }; 20 | 21 | return $data; 22 | } 23 | 24 | public static function authorization() 25 | { 26 | $authorization = getallheaders(); 27 | 28 | if (!isset($authorization['Authorization'])) return ['error' => 'Sorry, no authorization header provided']; 29 | 30 | $authorizationPartials = explode(' ', $authorization['Authorization']); 31 | 32 | if (count($authorizationPartials) != 2) return ['error'=> 'Please, provide a valid authorization header.']; 33 | 34 | return $authorizationPartials[1] ?? ''; 35 | } 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Eric Neves 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api/src/Http/Route.php: -------------------------------------------------------------------------------- 1 | $path, 13 | 'action' => $action, 14 | 'method' => 'GET' 15 | ]; 16 | } 17 | 18 | public static function post(string $path, string $action) 19 | { 20 | self::$routes[] = [ 21 | 'path' => $path, 22 | 'action' => $action, 23 | 'method' => 'POST' 24 | ]; 25 | } 26 | 27 | public static function put(string $path, string $action) 28 | { 29 | self::$routes[] = [ 30 | 'path' => $path, 31 | 'action' => $action, 32 | 'method' => 'PUT' 33 | ]; 34 | } 35 | 36 | public static function delete(string $path, string $action) 37 | { 38 | self::$routes[] = [ 39 | 'path' => $path, 40 | 'action' => $action, 41 | 'method' => 'DELETE' 42 | ]; 43 | } 44 | 45 | public static function routes() 46 | { 47 | return self::$routes; 48 | } 49 | } -------------------------------------------------------------------------------- /api/src/Core/Core.php: -------------------------------------------------------------------------------- 1 | true, 33 | 'success' => false, 34 | 'message' => 'Sorry, method not allowed.' 35 | ], 405); 36 | return; 37 | } 38 | 39 | [$controller, $action] = explode('@', $route['action']); 40 | 41 | $controller = $prefixController . $controller; 42 | $extendController = new $controller(); 43 | $extendController->$action(new Request, new Response, $matches); 44 | } 45 | } 46 | 47 | if (!$routeFound) { 48 | $controller = $prefixController . 'NotFoundController'; 49 | $extendController = new $controller(); 50 | $extendController->index(new Request, new Response); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /api/src/Http/JWT.php: -------------------------------------------------------------------------------- 1 | 'JWT', 'alg' => 'HS256']); 12 | $payload = json_encode($data); 13 | 14 | $base64UrlHeader = self::base64url_encode($header); 15 | $base64UrlPayload = self::base64url_encode($payload); 16 | 17 | $signature = self::signature($base64UrlHeader, $base64UrlPayload); 18 | 19 | $jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $signature; 20 | 21 | return $jwt; 22 | } 23 | 24 | public static function verify(string $jwt) 25 | { 26 | $tokenPartials = explode('.', $jwt); 27 | 28 | if (count($tokenPartials) != 3) return false; 29 | 30 | [$header, $payload, $signature] = $tokenPartials; 31 | 32 | if ($signature !== self::signature($header, $payload)) return false; 33 | 34 | return self::base64url_decode($payload); 35 | } 36 | 37 | public static function signature(string $header, string $payload) 38 | { 39 | $signature = hash_hmac('sha256', $header . "." . $payload, self::$secret, true); 40 | 41 | return self::base64url_encode($signature); 42 | } 43 | 44 | public static function base64url_encode($data) 45 | { 46 | return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 47 | } 48 | 49 | public static function base64url_decode($data) 50 | { 51 | $padding = strlen($data) % 4; 52 | 53 | $padding !== 0 && $data .= str_repeat('=', 4 - $padding); 54 | 55 | $data = strtr($data, '-_', '+/'); 56 | 57 | return json_decode(base64_decode($data), true); 58 | } 59 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |
4 | 10 | Este repositório contém o código-fonte de uma API desenvolvida em PHP puro. A API é demonstrada em um vídeo tutorial disponível no YouTube, criado pelo autor deste repositório. 11 |
12 |13 | O vídeo tutorial associado a este repositório pode ser acessado aqui. 🚀 14 |
15 | 16 |17 | Se gostou, deixe sua 🌟 no projeto! 18 |
19 | 20 |  21 | 22 | ### Descrição 23 | 24 | A API em PHP puro foi desenvolvida como parte de um tutorial prático, projetado para ensinar os conceitos fundamentais de criação de APIs usando PHP. No vídeo tutorial associado a este repositório, você aprenderá a construir uma API simples, utilizando apenas PHP e algumas práticas recomendadas. 25 | 26 | ### Vídeo Tutorial 27 | 28 | O vídeo tutorial associado a este repositório pode ser acessado aqui. 29 | 30 | Principais Recursos: 31 | * PSR-4 32 | * HTTP 33 | * Request 34 | * Response 35 | * HTTP Method 36 | * Autenticação por JWT 37 | * Rotas 38 | * Banco de Dados 39 | * CRUD (Create, Read, Update, Delete) 40 | 41 | ### Execução 42 | 43 | ```sh 44 | 45 | # Clone Repository 46 | $ git clone https://github.com/EricNeves/yt-api-com-php.git 47 | 48 | # Folder 49 | $ cp yt-api-com-php/ /var/www/html 50 | 51 | # Install Dependencies - PHP 52 | $ cd yt-api-com-php/ && composer update 53 | 54 | ``` 55 | 56 | Mova o projeto para dentro do seu servidor Apache ou NGINX: 57 | 58 | * API: http://localhost/yt-api-com-php/ 59 | 60 | ### License 61 | 62 |