- 1 - Requisitos
- 2 - Criando a estrutura de diretórios
- 3 - Configurando o arquivo .htaccess
- 4 - Criando o arquivo de configuração
- 5 - Criando o arquivo de conexão com o banco de dados
- 6 - Criando o arquivo de rotas
- 7 - Definindo modelos (Model)
- 8 - Implementando controladores (Controller)
- 9 - Testando a API
- Conclusão:
Neste tutorial, você aprenderá como criar uma REST API em PHP do zero, sem usar dependências externas. Aprenda a estruturar, configurar e testar sua própria API e dê vida às suas aplicações web.
Quer saber mais sobre APIs REST? Visite nosso post em REST API: O que é e como funciona?
1 – Requisitos
Antes de começarmos a criar nossa REST API em PHP sem usar dependências, certifique-se de que você tenha os seguintes requisitos instalados e configurados em seu ambiente de desenvolvimento:
- Servidor Web: Um servidor web capaz de executar PHP, como o Apache ou o Nginx.
- PHP: A linguagem de programação PHP na versão 7.4 ou superior. Verifique se as extensões necessárias estão habilitadas (por exemplo, MySQLi, PDO, etc.).
- Banco de dados: Um banco de dados para armazenar e gerenciar os dados da sua API. O MySQL é uma opção popular, mas você pode escolher outro banco de dados que seja compatível com PHP, como PostgreSQL ou SQLite.
- Ferramenta de teste de API: Um cliente REST para testar suas rotas e funcionalidades da API, como Postman ou Insomnia.
- Editor de código-fonte: Um editor de código-fonte de sua escolha para escrever e editar o código PHP, como Visual Studio Code, PhpStorm, Sublime Text ou Atom.
Uma vez que todos os requisitos estejam instalados e configurados corretamente, você pode prosseguir com a criação da REST API em PHP.
2 – Criando a estrutura de diretórios
Organizar a estrutura de diretórios é fundamental para manter seu projeto limpo e fácil de entender. Vamos criar a estrutura de diretórios para nossa REST API em PHP. No diretório raiz do seu projeto, crie os seguintes diretórios e arquivos:
rest-api-php/
│
├── .htaccess
├── config/
│ └── config.php
│
├── controllers/
│
├── models/
│
├── routes/
│ └── routes.php
│
└── utils/
└── database.php
Explicação da estrutura:
.htaccess
: Arquivo de configuração do Apache para reescrever URLs e outras configurações específicas do servidor.config/
: Diretório que armazena o arquivo de configuração do projeto.config.php
: Arquivo de configuração com parâmetros, como informações do banco de dados e outras configurações globais.
controllers/
: Diretório que armazena os controladores responsáveis por manipular as requisições e respostas da API.models/
: Diretório que armazena os modelos responsáveis pela lógica de negócios e interação com o banco de dados.routes/
: Diretório que armazena o arquivo de rotas.routes.php
: Arquivo responsável por mapear as rotas da API para os controladores correspondentes.
utils/
: Diretório que armazena arquivos utilitários e de serviços, como a conexão com o banco de dados.database.php
: Arquivo responsável pela conexão com o banco de dados.
Agora que criamos a estrutura de diretórios, podemos seguir para a configuração do arquivo .htaccess e a implementação dos arquivos de configuração, conexão com o banco de dados, rotas, modelos e controladores.
3 – Configurando o arquivo .htaccess
O arquivo .htaccess
é usado para configurar o servidor Apache e permitir a reescrita de URLs, o que é importante para criar uma API RESTful. Abra o arquivo .htaccess
na raiz do projeto e adicione o seguinte conteúdo:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ routes/routes.php [QSA,L]
Explicação das regras:
RewriteEngine On
: Habilita o mecanismo de reescrita do Apache.RewriteCond %{REQUEST_FILENAME} !-d
: Verifica se a solicitação não corresponde a um diretório existente.RewriteCond %{REQUEST_FILENAME} !-f
: Verifica se a solicitação não corresponde a um arquivo existente.RewriteRule ^(.+)$ routes/routes.php [QSA,L]
: Redireciona todas as solicitações que não correspondem a arquivos ou diretórios existentes para o arquivoroutes/routes.php
. A flag[QSA]
(Query String Append) preserva a string de consulta, enquanto a flag[L]
(Last) indica que esta é a última regra de reescrita a ser aplicada.
Certifique-se de que o módulo mod_rewrite
do Apache esteja habilitado em seu servidor. Se você estiver usando o Nginx ou outro servidor web, consulte a documentação correspondente para configurar a reescrita de URLs.
Com o arquivo .htaccess
configurado, o servidor web redirecionará todas as solicitações para o arquivo routes/routes.php
, permitindo que você gerencie as rotas da API de maneira centralizada.
4 – Criando o arquivo de configuração
O arquivo de configuração config.php
armazenará as informações de configuração do projeto, como os detalhes do banco de dados e outras configurações globais. Abra o arquivo config/config.php
e adicione o seguinte conteúdo:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'your_database_name');
define('DB_USER', 'your_database_user');
define('DB_PASSWORD', 'your_database_password');
define('DEBUG', true); // Altere para 'false' no ambiente de produção
Substitua 'your_database_name'
, 'your_database_user'
e 'your_database_password'
pelos detalhes do seu banco de dados.
DB_HOST
: O endereço do servidor de banco de dados.DB_NAME
: O nome do banco de dados.DB_USER
: O nome de usuário do banco de dados.DB_PASSWORD
: A senha do usuário do banco de dados.DEBUG
: Um sinalizador para controlar o modo de depuração do projeto. Defina comotrue
no ambiente de desenvolvimento efalse
no ambiente de produção.
Agora que você criou o arquivo de configuração, as informações do banco de dados e outras configurações globais estão disponíveis em todo o projeto através das constantes definidas.
5 – Criando o arquivo de conexão com o banco de dados
O arquivo database.php
gerenciará a conexão com o banco de dados. Abra o arquivo utils/database.php
e adicione o seguinte conteúdo:
<?php
require_once '../config/config.php';
class Database {
private $connection;
public function __construct() {
$this->connect();
}
private function connect() {
$this->connection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if ($this->connection->connect_error) {
die("Connection failed: " . $this->connection->connect_error);
}
}
public function getConnection() {
return $this->connection;
}
}
Neste arquivo, criamos uma classe chamada Database
para gerenciar a conexão com o banco de dados. A classe contém os seguintes métodos:
__construct()
: Construtor da classe que chama o métodoconnect()
para estabelecer a conexão com o banco de dados.connect()
: Método privado que cria uma nova conexão com o banco de dados usando a extensãomysqli
. Se houver um erro de conexão, o script será encerrado e a mensagem de erro será exibida.getConnection()
: Método público que retorna a conexão estabelecida com o banco de dados.
Agora, a conexão com o banco de dados está pronta para ser usada nos modelos do projeto.
6 – Criando o arquivo de rotas
O arquivo routes.php
gerencia todas as rotas da API e direciona as solicitações para os controladores apropriados. Abra o arquivo routes/routes.php
e adicione o seguinte conteúdo:
<?php
require_once '../controllers/example_controller.php';
$requestMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$uriSegments = explode('/', parse_url($uri, PHP_URL_PATH));
$dbConnection = (new Database())->getConnection();
$controller = new ExampleController($dbConnection);
if ($uriSegments[1] === 'example') {
$id = isset($uriSegments[2]) ? intval($uriSegments[2]) : null;
switch ($requestMethod) {
case 'GET':
if ($id) {
$response = $controller->get($id);
} else {
$response = $controller->getAll();
}
break;
case 'POST':
$response = $controller->create();
break;
case 'PUT':
if ($id) {
$response = $controller->update($id);
} else {
$response = ['status' => 'error', 'message' => 'Invalid example ID'];
}
break;
case 'DELETE':
if ($id) {
$response = $controller->delete($id);
} else {
$response = ['status' => 'error', 'message' => 'Invalid example ID'];
}
break;
default:
$response = ['status' => 'error', 'message' => 'Invalid request method'];
break;
}
} else {
$response = ['status' => 'error', 'message' => 'Invalid API endpoint'];
}
header('Content-Type: application/json');
echo json_encode($response);
Neste arquivo, primeiro definimos os cabeçalhos para permitir CORS e informar ao cliente que estamos retornando dados no formato JSON.
Em seguida, importamos os arquivos necessários e verificamos o método da solicitação HTTP e a URI para direcionar a solicitação para o controlador e ação apropriados.
Por enquanto, usamos um controlador de exemplo chamado example_controller
. Você pode substituí-lo pelos controladores que desejar criar para sua API. As rotas estão configuradas para lidar com os métodos GET, POST, PUT e DELETE. O arquivo routes.php
direciona as solicitações para os métodos apropriados do controlador e retorna a resposta em formato JSON.
No próximo passo, você criará os modelos e controladores que serão usados pela API.
7 – Definindo modelos (Model)
Os modelos são responsáveis pela lógica de negócios e interação com o banco de dados. Neste exemplo, vamos criar um modelo de exemplo chamado Example
. Crie um arquivo chamado example_model.php
no diretório models/
e adicione o seguinte conteúdo:
<?php
class ExampleModel {
private $conn;
public function __construct($dbConnection) {
$this->conn = $dbConnection;
}
public function getAll() {
$query = "SELECT * FROM examples";
$result = $this->conn->query($query);
return $result;
}
public function get($id) {
$query = "SELECT * FROM examples WHERE id = ?";
$stmt = $this->conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
return $result;
}
public function create($data) {
$query = "INSERT INTO examples (name, description) VALUES (?, ?)";
$stmt = $this->conn->prepare($query);
$stmt->bind_param('ss', $data['name'], $data['description']);
if ($stmt->execute()) {
return ['status' => 'success', 'message' => 'Foi criado com sucesso'];
} else {
return ['status' => 'error', 'message' => 'Erro ao criar'];
}
}
public function update($id, $data) {
$query = "UPDATE examples SET name = ?, description = ? WHERE id = ?";
$stmt = $this->conn->prepare($query);
$stmt->bind_param('ssi', $data['name'], $data['description'], $id);
if ($stmt->execute()) {
return ['status' => 'success', 'message' => 'Foi atualizado com sucesso'];
} else {
return ['status' => 'error', 'message' => 'Erro ao atualizar'];
}
}
public function delete($id) {
$query = "DELETE FROM examples WHERE id = ?";
$stmt = $this->conn->prepare($query);
$stmt->bind_param('i', $id);
if ($stmt->execute()) {
return ['status' => 'success', 'message' => 'Foi deletado com sucesso'];
} else {
return ['status' => 'error', 'message' => 'Erro ao deletar'];
}
}
}
Neste exemplo, criamos uma classe ExampleModel
que contém os seguintes métodos:
__construct($dbConnection)
: Construtor da classe que recebe a conexão com o banco de dados e a armazena em uma variável privada.getAll()
: Método que retorna todos os registros da tabelaexamples
.get($id)
: Método que retorna um registro específico da tabelaexamples
com base em seu ID.create($data)
: Método para criar um novo registro na tabelaexamples
.update($id, $data)
: Método para atualizar um registro existente na tabelaexamples
com base em seu ID.delete($id)
: Método para excluir um registro da tabelaexamples
com base em seu ID.
Você deve substituir os nomes das tabelas e colunas pelos nomes reais do seu banco de dados e implementar a lógica nos métodos create
, update
e delete
de acordo com suas necessidades.
Depois de criar o modelo, você pode implementar o controlador correspondente.
8 – Implementando controladores (Controller)
Os controladores são responsáveis por manipular as requisições e respostas da API. Neste exemplo, criaremos um controlador chamado ExampleController
para trabalhar com o modelo Example
criado anteriormente. Crie um arquivo chamado example_controller.php
no diretório controllers/
e adicione o seguinte conteúdo:
<?php
require_once '../models/example_model.php';
class ExampleController {
private $model;
public function __construct($dbConnection) {
$this->model = new ExampleModel($dbConnection);
}
public function getAll() {
$result = $this->model->getAll();
$examples = [];
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
array_push($examples, $row);
}
return ['status' => 'success', 'data' => $examples];
} else {
return ['status' => 'error', 'message' => 'No examples found'];
}
}
public function get($id) {
$result = $this->model->get($id);
if ($result->num_rows > 0) {
$example = $result->fetch_assoc();
return ['status' => 'success', 'data' => $example];
} else {
return ['status' => 'error', 'message' => 'Example not found'];
}
}
public function create() {
$data = json_decode(file_get_contents('php://input'), true);
if (!empty($data['name']) && !empty($data['description'])) {
$result = $this->model->create($data);
return $result;
} else {
return ['status' => 'error', 'message' => 'Name and description fields are required'];
}
}
public function update($id) {
$data = json_decode(file_get_contents('php://input'), true);
if (!empty($data['name']) && !empty($data['description'])) {
$result = $this->model->update($id, $data);
return $result;
} else {
return ['status' => 'error', 'message' => 'Name and description fields are required'];
}
}
public function delete($id) {
if (!empty($id)) {
$result = $this->model->delete($id);
return $result;
} else {
return ['status' => 'error', 'message' => 'Invalid example ID'];
}
}
}
Neste exemplo, criamos uma classe ExampleController
que contém os seguintes métodos:
__construct($dbConnection)
: Construtor da classe que recebe a conexão com o banco de dados e instancia o modeloExampleModel
.getAll()
: Método que obtém todos os registros usando o modelo e retorna a resposta no formato apropriado.get($id)
: Método que obtém um registro específico usando o modelo e retorna a resposta no formato apropriado.create()
: Método para criar um novo registro usando o modelo e retornar a resposta no formato apropriado.update($id)
: Método para atualizar um registro existente usando o modelo e retornar a resposta no formato apropriado.delete($id)
: Método para excluir um registro usando o modelo e retornar a resposta no formato apropriado.
Você deve implementar a lógica nos métodos create
, update
e delete
de acordo com suas necessidades. O controlador manipula a resposta e retorna os dados no formato apropriado para serem exibidos pelo arquivo routes/routes.php
.
Agora que você implementou o controlador, a API está pronta para ser testada.
9 – Testando a API
Para testar a API, você pode usar um cliente HTTP como Postman, Insomnia ou até mesmo o cURL no terminal. Como exemplo, vamos supor que você esteja usando a seguinte estrutura de tabela no banco de dados:
CREATE TABLE examples (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT
);
Certifique-se de ter alguns registros na tabela examples
para testar a API corretamente.
Aqui estão alguns exemplos de como testar a API com diferentes métodos HTTP:
GET (listar todos os registros):
URL: http://localhost/example
Método: GET
GET (obter um registro específico):
URL: http://localhost/example/1
Método: GET
POST (criar um novo registro):
URL: http://localhost/example
Método: POST
Headers: Content-Type: application/json
Body:
{
"name": "Joao Almeida",
"description": "Uma descrição para este exemplo."
}
PUT (atualizar um registro existente):
URL: http://localhost/example/1
Método: PUT
Headers: Content-Type: application/json
Body:
{
"name": "Valor Atualizado",
"description": "Descrição para este exemplo de atualização."
}
DELETE (excluir um registro):
URL: http://localhost/example/1
Método: DELETE
Lembre-se de substituir localhost
pelo endereço do seu servidor, se aplicável. Ao testar a API, você deve ver as respostas em JSON de acordo com as operações realizadas. Certifique-se de implementar a lógica nos métodos create
, update
e delete
no controlador antes de testar essas ações.
Conclusão:
Agora você possui todas as habilidades necessárias para criar uma REST API em PHP do zero. Com este guia, você aprendeu a estruturar, configurar e testar sua API, tornando-se apto a implementar soluções robustas e escaláveis para suas aplicações web. Continue explorando e aprimorando suas habilidades em PHP e APIs REST!