📄 file_get_contents()
file_get_contents() é uma função nativa do PHP que lê o conteúdo de um ficheiro ou URL para uma string. É a forma mais simples de fazer pedidos HTTP em PHP.
Sintaxe Básica
string file_get_contents(
string $filename,
bool $use_include_path = false,
?resource $context = null,
int $offset = 0,
?int $length = null
): string|false
Quando Usar?
✅ Ideal Para
- Pedidos GET simples
- APIs públicas sem autenticação
- Scripts rápidos e simples
- Quando não tens acesso a extensões externas
❌ Evitar Para
- Pedidos POST/PUT complexos
- APIs com autenticação avançada
- Quando precisas de timeouts personalizados
- Projetos profissionais grandes
Precisas de ter allow_url_fopen = On no php.ini. Muitos servidores partilhados têm isto desativado por segurança!
🔍 GET Simples
O uso mais básico: fazer um pedido GET e obter a resposta.
Exemplo com JSONPlaceholder
<?php
// URL da API pública (JSONPlaceholder - API fake para testes)
$url = 'https://jsonplaceholder.typicode.com/posts/1';
// Fazer o pedido
$response = file_get_contents($url);
// Verificar se houve erro
if ($response === false) {
die('Erro ao fazer pedido à API');
}
// Decodificar JSON
$data = json_decode($response, true);
// Mostrar resultado
echo "ID: " . $data['id'] . "\n";
echo "Título: " . $data['title'] . "\n";
echo "Conteúdo: " . $data['body'] . "\n";
?>
Resultado
ID: 1
Título: sunt aut facere repellat provident
Conteúdo: quia et suscipit
suscipit recusandae consequuntur...
Parâmetros na URL (Query String)
<?php
// Construir URL com parâmetros
$baseUrl = 'https://jsonplaceholder.typicode.com/posts';
$params = [
'userId' => 1,
'_limit' => 5
];
$url = $baseUrl . '?' . http_build_query($params);
// Resultado: https://jsonplaceholder.typicode.com/posts?userId=1&_limit=5
$response = file_get_contents($url);
$posts = json_decode($response, true);
foreach ($posts as $post) {
echo $post['title'] . "\n";
}
?>
Usa http_build_query($array) para converter um array associativo em query string. Lida automaticamente com encoding de caracteres especiais!
⚙️ stream_context_create()
Para pedidos mais avançados, precisas de criar um contexto de stream com stream_context_create().
Estrutura do Contexto
<?php
$context = stream_context_create([
'http' => [
'method' => 'GET', // Método HTTP
'header' => [ // Headers
'User-Agent: Meu App PHP',
'Accept: application/json',
'Authorization: Bearer token123'
],
'timeout' => 30, // Timeout em segundos
'ignore_errors' => true // Não lançar erro em códigos 4xx/5xx
]
]);
$url = 'https://api.exemplo.com/dados';
$response = file_get_contents($url, false, $context);
?>
Opções Disponíveis
| Opção | Tipo | Descrição |
|---|---|---|
method |
string | GET, POST, PUT, DELETE, etc. |
header |
string|array | Headers HTTP (um por linha ou array) |
content |
string | Body do pedido (para POST/PUT) |
timeout |
int | Timeout em segundos |
ignore_errors |
bool | Ler resposta mesmo com status de erro |
follow_location |
int | Seguir redireções (0=Não, 1=Sim) |
📤 Pedidos POST
Para enviar dados via POST, precisas de usar stream_context_create() com o body do pedido.
POST com JSON
<?php
$url = 'https://jsonplaceholder.typicode.com/posts';
// Dados a enviar
$data = [
'title' => 'Meu Post',
'body' => 'Conteúdo do post aqui',
'userId' => 1
];
// Criar contexto
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => [
'Content-Type: application/json',
'Accept: application/json'
],
'content' => json_encode($data)
]
]);
// Fazer pedido
$response = file_get_contents($url, false, $context);
// Verificar resposta
if ($response === false) {
// Lidar com erro
$error = error_get_last();
echo "Erro: " . $error['message'];
} else {
$result = json_decode($response, true);
print_r($result);
}
?>
POST com Form Data
<?php
$url = 'https://api.exemplo.com/submit';
// Dados como formulário
$data = [
'nome' => 'João Silva',
'email' => 'joao@exemplo.com',
'mensagem' => 'Olá, mundo!'
];
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($data)
]
]);
$response = file_get_contents($url, false, $context);
?>
Lembra-te de definir o Content-Type correto nos headers:
- JSON:
Content-Type: application/json - Form Data:
Content-Type: application/x-www-form-urlencoded
📋 Custom Headers
Headers são essenciais para autenticação, definir o tipo de conteúdo aceites, e outros propósitos.
Headers Comuns
<?php
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => [
'Accept: application/json', // Tipo de conteúdo aceite
'Content-Type: application/json', // Tipo de conteúdo enviado
'Authorization: Bearer TOKEN_AQUI', // Autenticação
'User-Agent: MeuApp/1.0', // Identificação da app
'Accept-Language: pt-PT', // Idioma preferido
'X-Custom-Header: valor' // Header personalizado
]
]
]);
$response = file_get_contents($url, false, $context);
?>
API Key no Header
<?php
$apiKey = 'sua_api_key_aqui';
$url = 'https://api.exemplo.com/dados';
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => [
'X-API-KEY: ' . $apiKey,
// ou
'Authorization: ApiKey ' . $apiKey
]
]
]);
$response = file_get_contents($url, false, $context);
?>
🚨 Tratamento de Erros
Verificar Erros
<?php
function fetchApi(string $url, array $options = []) {
// Configurações padrão
$defaultOptions = [
'method' => 'GET',
'headers' => [],
'body' => null,
'timeout' => 30
];
$options = array_merge($defaultOptions, $options);
// Construir contexto
$contextOptions = [
'http' => [
'method' => $options['method'],
'header' => $options['headers'],
'timeout' => $options['timeout'],
'ignore_errors' => true // Importante!
]
];
if ($options['body'] !== null) {
$contextOptions['http']['content'] = $options['body'];
}
$context = stream_context_create($contextOptions);
// Fazer pedido com tratamento de erros
set_error_handler(function($errno, $errstr) {
throw new Exception("Erro de rede: $errstr");
});
try {
$response = file_get_contents($url, false, $context);
if ($response === false) {
throw new Exception("Falha ao obter resposta");
}
// Obter headers de resposta
$responseHeaders = $http_response_header ?? [];
$statusCode = $this->extractStatusCode($responseHeaders);
return [
'status' => $statusCode,
'headers' => $responseHeaders,
'body' => $response,
'data' => json_decode($response, true)
];
} catch (Exception $e) {
return [
'status' => 0,
'error' => $e->getMessage(),
'body' => null,
'data' => null
];
} finally {
restore_error_handler();
}
}
// Extrair código de status dos headers
function extractStatusCode(array $headers): int {
if (isset($headers[0]) && preg_match('/HTTP\/\d+\.?\d*\s+(\d+)/', $headers[0], $matches)) {
return (int) $matches[1];
}
return 0;
}
?>
Uso da Função
<?php
$result = fetchApi('https://jsonplaceholder.typicode.com/posts/1');
if ($result['status'] === 200) {
echo "Título: " . $result['data']['title'];
} elseif ($result['status'] >= 400) {
echo "Erro HTTP: " . $result['status'];
} else {
echo "Erro: " . $result['error'];
}
?>
A variável $http_response_header é preenchida automaticamente pelo PHP após um file_get_contents() bem-sucedido. Contém os headers da resposta!
⚠️ Limitações
Desvantagens de file_get_contents()
❌ Sem Controlo de Timeout
O timeout padrão é muito alto. Podes configurar no contexto, mas não é tão flexível como cURL.
❌ Sem Suporte a SSL Avançado
Não podes configurar certificados SSL personalizados facilmente.
❌ Mensagens de Erro Vagas
Quando falha, a mensagem de erro não é muito útil para debug.
❌ Dependência de Configuração
Requer allow_url_fopen = On no php.ini.
Comparação com cURL
| Funcionalidade | file_get_contents() | cURL |
|---|---|---|
| Simplicidade | ✅ Muito simples | ⚠️ Mais complexo |
| Timeout Granular | ❌ Limitado | ✅ Controlo total |
| Cookies | ⚠️ Possível mas difícil | ✅ Suporte nativo |
| SSL/Certificados | ❌ Limitado | ✅ Controlo total |
| Debug | ❌ Mensagens vagas | ✅ Detalhado |
| Performance | ✅ Bom para simples | ✅ Melhor para complexos |
| Requisitos | ⚠️ allow_url_fopen | ✅ Extensão cURL |
- file_get_contents(): Pedidos GET simples, protótipos rápidos, scripts internos.
- cURL: APIs em produção, autenticação complexa, timeouts críticos, cookies, SSL avançado.
- Guzzle: Aplicações profissionais, interface limpa, PSR-7, middleware.
📝 Exercícios
Exercício 1: GET Básico
Desafio: Usa file_get_contents() para obter o utilizador com ID 2 da API JSONPlaceholder e mostra o nome e email.
URL: https://jsonplaceholder.typicode.com/users/2
<?php
$url = 'https://jsonplaceholder.typicode.com/users/2';
$response = file_get_contents($url);
$user = json_decode($response, true);
echo "Nome: " . $user['name'] . "\n";
echo "Email: " . $user['email'] . "\n";
?>
Exercício 2: POST com JSON
Desafio: Cria um novo post na API JSONPlaceholder com título "Meu Post" e body "Conteúdo de teste".
<?php
$url = 'https://jsonplaceholder.typicode.com/posts';
$data = [
'title' => 'Meu Post',
'body' => 'Conteúdo de teste',
'userId' => 1
];
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode($data)
]
]);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
print_r($result);
?>
Exercício 3: Headers Customizados
Desafio: Faz um pedido GET com um header de autenticação Authorization: Bearer meu-token-123.
<?php
$url = 'https://jsonplaceholder.typicode.com/posts';
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'Authorization: Bearer meu-token-123'
]
]);
$response = file_get_contents($url, false, $context);
$posts = json_decode($response, true);
?>