Operações Bitwise em PHP
Guia completo sobre operadores bitwise em PHP: manipulação de bits, flags, permissões e otimizações
🔢 Operações Bitwise em PHP
As operações bitwise (bit a bit) manipulam dados no nível mais fundamental: bits individuais. Embora menos comuns no dia a dia, são extremamente poderosas para otimizações, sistemas de permissões, flags e processamento de baixo nível.
🎓 Entendendo Binário do Zero
Antes de mergulhar nos operadores bitwise, vamos entender como os computadores realmente enxergam os números.
O que é um Bit?
Um bit é a menor unidade de informação em um computador. Ele pode ter apenas dois valores:
- 0 (desligado, falso, sem corrente elétrica)
- 1 (ligado, verdadeiro, com corrente elétrica)
Pense em um bit como um interruptor de luz: ele está ligado (1) ou desligado (0).
Como Formar Números com Bits?
Os computadores usam o sistema binário (base 2) para representar números. No nosso dia a dia, usamos o sistema decimal (base 10), que tem 10 dígitos (0-9).
No sistema decimal:
345 = (3 × 100) + (4 × 10) + (5 × 1)
= (3 × 10²) + (4 × 10¹) + (5 × 10⁰)
No sistema binário (base 2):
1011 = (1 × 8) + (0 × 4) + (1 × 2) + (1 × 1)
= (1 × 2³) + (0 × 2²) + (1 × 2¹) + (1 × 2⁰)
= 8 + 0 + 2 + 1
= 11 (em decimal)
Tabela de Potências de 2
Esta é a chave para entender binário:
| Posição | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Valor | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| Potência | 2⁷ | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
Exemplos Práticos de Conversão
Exemplo 1: Decimal 5 → Binário
Qual é 5 em binário?
128? NÃO (muito grande)
64? NÃO (muito grande)
32? NÃO (muito grande)
16? NÃO (muito grande)
8? NÃO (muito grande)
4? SIM! (sobram 1) → bit 1
2? NÃO (muito grande para o resto)
1? SIM! (fecha) → bit 1
Resultado: 0000 0101
│││└ 1 = 1
││└─ 2 = 0
│└── 4 = 1
└─── 8 = 0
5 em binário = 0101 ou simplesmente 101
Exemplo 2: Binário 1101 → Decimal
1101 = ?
Posição: 3 2 1 0
Bit: 1 1 0 1
Valor: 8 4 2 1
Cálculo: (1×8) + (1×4) + (0×2) + (1×1)
= 8 + 4 + 0 + 1
= 13
1101 em decimal = 13
Visualizando Bits em PHP
<?php
// Converter decimal para binário
$numero = 13;
$binario = decbin($numero);
echo "$numero em binário: $binario\n";
// Saída: 13 em binário: 1101
// Converter binário para decimal
$binario = '1101';
$decimal = bindec($binario);
echo "$binario em decimal: $decimal\n";
// Saída: 1101 em decimal: 13
// Exibir em formato de 8 bits (1 byte)
$numero = 5;
$binario8bits = str_pad(decbin($numero), 8, '0', STR_PAD_LEFT);
echo "$numero em 8 bits: $binario8bits\n";
// Saída: 5 em 8 bits: 00000101
// Saída esperada
// 13 em binário: 1101
// 1101 em decimal: 13
// 5 em 8 bits: 00000101
🎯 Como Funcionam as Operações Bitwise?
Agora que você entende binário, vamos ver como manipular bits individuais!
A Lógica Por Trás
Operações bitwise trabalham bit por bit, comparando os bits na mesma posição de dois números.
Exemplo Visual: AND (&)
Imagine que você tem dois números:
Número A = 5 → 0101
Número B = 3 → 0011
O operador AND (&) pergunta para cada posição:
"Os DOIS bits são 1?"
Posição 3: 0 E 0 = 0 (não, nenhum é 1)
Posição 2: 1 E 0 = 0 (não, apenas um é 1)
Posição 1: 0 E 1 = 0 (não, apenas um é 1)
Posição 0: 1 E 1 = 1 (SIM! ambos são 1)
Resultado: 0001 (decimal 1)
<?php
echo 5 & 3; // Saída: 1
// Visualizando passo a passo:
echo "5 em binário: " . decbin(5) . "\n"; // 101
echo "3 em binário: " . decbin(3) . "\n"; // 11
echo "Resultado: " . decbin(5 & 3) . "\n"; // 1
// Saída esperada
// 15 em binário: 101
// 3 em binário: 11
// Resultado: 1
Exemplo Visual: OR (|)
O operador OR (|) pergunta:
"Pelo menos UM dos bits é 1?"
0101 (5)
| 0011 (3)
--------
0111 (7)
Posição 3: 0 OU 0 = 0 (nenhum é 1)
Posição 2: 1 OU 0 = 1 (pelo menos um é 1!)
Posição 1: 0 OU 1 = 1 (pelo menos um é 1!)
Posição 0: 1 OU 1 = 1 (ambos são 1!)
<?php
echo 5 | 3; // Saída: 7
// Saída esperada
// 7
Exemplo Visual: XOR (^)
O operador XOR (^) pergunta:
"Os bits são DIFERENTES?"
0101 (5)
^ 0011 (3)
--------
0110 (6)
Posição 3: 0 ≠ 0? NÃO → 0
Posição 2: 1 ≠ 0? SIM → 1
Posição 1: 0 ≠ 1? SIM → 1
Posição 0: 1 ≠ 1? NÃO → 0
<?php
echo 5 ^ 3; // Saída: 6
// Saída esperada
// 6
Deslocamento de Bits (Shift)
Left Shift (<<) - Deslocamento à Esquerda
Imagine os bits caminhando para a esquerda:
5 << 1 significa "desloque 5 uma posição à esquerda"
Antes: 0000 0101 (5)
Depois: 0000 1010 (10)
←←←←
Os bits se movem para esquerda, zeros entram pela direita
Cada deslocamento à esquerda = multiplicar por 2
<?php
echo 5 << 1; // 10 (5 × 2)
echo 5 << 2; // 20 (5 × 4)
echo 5 << 3; // 40 (5 × 8)
// Visualizando:
// 5 << 1: 0101 → 1010 = 10
// 5 << 2: 0101 → 10100 = 20
// 5 << 3: 0101 → 101000 = 40
// Saída esperada
// 102040
Right Shift (>>) - Deslocamento à Direita
Os bits caminham para a direita:
20 >> 1 significa "desloque 20 uma posição à direita"
Antes: 0001 0100 (20)
Depois: 0000 1010 (10)
→→→→
Os bits à direita "caem fora"
Cada deslocamento à direita = dividir por 2 (arredonda para baixo)
<?php
echo 20 >> 1; // 10 (20 ÷ 2)
echo 20 >> 2; // 5 (20 ÷ 4)
echo 21 >> 1; // 10 (21 ÷ 2 = 10.5 → arredonda para 10)
// Visualizando:
// 20 >> 1: 10100 → 1010 = 10
// 20 >> 2: 10100 → 101 = 5
// Saída esperada
// 10510
Por Que Isso É Útil?
<?php
// ✅ Verificar se número é PAR (bit mais à direita é 0)
function isPar($n) {
return ($n & 1) === 0; // Se o último bit é 0, é par!
}
// Como funciona:
// 4 (par): 0100 & 0001 = 0000 → 0 (par!)
// 5 (ímpar): 0101 & 0001 = 0001 → 1 (ímpar!)
echo isPar(4) ? 'Par' : 'Ímpar'; // Par
echo isPar(5) ? 'Par' : 'Ímpar'; // Ímpar
// ✅ Multiplicar por 8 de forma super rápida
$resultado = 5 << 3; // 5 × 8 = 40
// Mais rápido que: $resultado = 5 * 8;
// ✅ Dividir por 4 de forma super rápida
$resultado = 20 >> 2; // 20 ÷ 4 = 5
// Mais rápido que: $resultado = (int)(20 / 4);
// Saída esperada
// ParÍmpar
🎨 Exemplo do Mundo Real: Sistema de Likert (Curtir/Favoritar)
Imagine uma rede social onde cada post pode ter múltiplas reações:
<?php
// Definindo as reações como potências de 2
define('LIKE', 1); // 0001
define('LOVE', 2); // 0010
define('HAHA', 4); // 0100
define('WOW', 8); // 1000
define('SAD', 16); // 10000
define('ANGRY', 32); // 100000
// João deu LIKE e LOVE em um post
$joaoReactions = LIKE | LOVE;
// 0001 | 0010 = 0011 (3 em decimal)
// Maria deu WOW e SAD
$mariaReactions = WOW | SAD;
// 1000 | 10000 = 11000 (24 em decimal)
// Verificar se João deu LIKE
if ($joaoReactions & LIKE) {
echo "João curtiu!\n";
}
// Verificar se Maria deu LIKE
if ($mariaReactions & LIKE) {
echo "Maria curtiu!\n";
} else {
echo "Maria NÃO curtiu\n"; // ← Essa mensagem aparece
}
// João muda de ideia e remove o LOVE
$joaoReactions = $joaoReactions & ~LOVE;
// 0011 & ~0010 = 0011 & 1101 = 0001
// Agora João só tem LIKE
// Contando quantas reações um post teve
$postReactions = LIKE | LOVE | HAHA; // 3 reações diferentes
function countReactions($reactions) {
$count = 0;
while ($reactions) {
if ($reactions & 1) $count++;
$reactions >>= 1;
}
return $count;
}
echo "Total de reações: " . countReactions($postReactions); // 3
// Saída esperada
// João curtiu!
// Maria NÃO curtiu
// Total de reações: 3
Por que usar bits?
- ✅ Compacto: 1 único número armazena múltiplas informações
- ✅ Rápido: operações bitwise são extremamente eficientes
- ✅ Elegante: código limpo e fácil de manter
📋 Operadores Bitwise
PHP oferece 6 operadores bitwise principais:
| Operador | Nome | Descrição | Exemplo |
|---|---|---|---|
& |
AND | Retorna 1 se ambos os bits forem 1 | 5 & 3 = 1 |
\| |
OR | Retorna 1 se pelo menos um bit for 1 | 5 \| 3 = 7 |
^ |
XOR | Retorna 1 se os bits forem diferentes | 5 ^ 3 = 6 |
~ |
NOT | Inverte todos os bits | ~5 = -6 |
<< |
Left Shift | Desloca bits para a esquerda | 5 << 1 = 10 |
>> |
Right Shift | Desloca bits para a direita | 5 >> 1 = 2 |
🎯 Operador AND (&)
Retorna 1 apenas quando ambos os bits são 1.
<?php
// Tabela verdade:
// 1 & 1 = 1
// 1 & 0 = 0
// 0 & 1 = 0
// 0 & 0 = 0
$a = 5; // 0101 em binário
$b = 3; // 0011 em binário
$result = $a & $b; // 0001 = 1
echo "$a & $b = $result\n";
// Saída: 5 & 3 = 1
// Verificação passo a passo:
// 0101 (5)
// & 0011 (3)
// ------
// 0001 (1)
// Saída esperada
// 5 & 3 = 1
Caso de Uso: Verificar se número é par ou ímpar
<?php
function isEven($num) {
return ($num & 1) === 0;
}
echo isEven(4) ? 'Par' : 'Ímpar'; // Par
echo isEven(7) ? 'Par' : 'Ímpar'; // Ímpar
// Saída esperada
// ParÍmpar
🎯 Operador OR (|)
Retorna 1 quando pelo menos um dos bits é 1.
<?php
$a = 5; // 0101
$b = 3; // 0011
$result = $a | $b; // 0111 = 7
echo "$a | $b = $result\n";
// Saída: 5 | 3 = 7
// Verificação:
// 0101 (5)
// | 0011 (3)
// ------
// 0111 (7)
// Saída esperada
// 5 | 3 = 7
Caso de Uso: Combinar flags/permissões
<?php
// Sistema de permissões
define('READ', 1); // 0001
define('WRITE', 2); // 0010
define('EXECUTE', 4); // 0100
define('DELETE', 8); // 1000
// Usuário com permissão de leitura e escrita
$userPermissions = READ | WRITE; // 0001 | 0010 = 0011 (3)
// Administrador com todas as permissões
$adminPermissions = READ | WRITE | EXECUTE | DELETE; // 15
🎯 Operador XOR (^)
Retorna 1 quando os bits são diferentes.
<?php
$a = 5; // 0101
$b = 3; // 0011
$result = $a ^ $b; // 0110 = 6
echo "$a ^ $b = $result\n";
// Saída: 5 ^ 3 = 6
// Verificação:
// 0101 (5)
// ^ 0011 (3)
// ------
// 0110 (6)
// Saída esperada
// 5 ^ 3 = 6
Caso de Uso: Trocar valores sem variável temporária
<?php
$a = 10;
$b = 20;
echo "Antes: a=$a, b=$b\n";
// Troca usando XOR
$a = $a ^ $b;
$b = $a ^ $b;
$a = $a ^ $b;
echo "Depois: a=$a, b=$b\n";
// Saída: a=20, b=10
// Saída esperada
// Antes: a=10, b=20
// Depois: a=20, b=10
🎯 Operador NOT (~)
Inverte todos os bits (complemento de um).
<?php
$a = 5; // 0000 0101
$result = ~$a; // 1111 1010 = -6 (complemento de dois)
echo "~$a = $result\n";
// Saída: ~5 = -6
// Em sistemas de complemento de dois: ~n = -(n+1)
// Saída esperada
// ~5 = -6
🎯 Left Shift (<<)
Desloca bits para a esquerda, preenchendo com zeros à direita. Equivale a multiplicar por 2^n.
<?php
$a = 5; // 0101
$result = $a << 1; // 1010 = 10
echo "$a << 1 = $result\n";
// Saída: 5 << 1 = 10
$result2 = $a << 2; // 10100 = 20
echo "$a << 2 = $result2\n";
// Saída: 5 << 2 = 20
// Fórmula: n << x = n * (2^x)
// Saída esperada
// 5 << 1 = 10
// 5 << 2 = 20
🎯 Right Shift (>>)
Desloca bits para a direita, descartando bits à direita. Equivale a dividir por 2^n (divisão inteira).
<?php
$a = 20; // 10100
$result = $a >> 1; // 01010 = 10
echo "$a >> 1 = $result\n";
// Saída: 20 >> 1 = 10
$result2 = $a >> 2; // 00101 = 5
echo "$a >> 2 = $result2\n";
// Saída: 20 >> 2 = 5
// Fórmula: n >> x = floor(n / 2^x)
// Saída esperada
// 20 >> 1 = 10
// 20 >> 2 = 5
🎮 Exemplo Prático: Sistema de Permissões
<?php
class Permissions {
const NONE = 0; // 0000
const READ = 1; // 0001
const WRITE = 2; // 0010
const EXECUTE = 4; // 0100
const DELETE = 8; // 1000
private $permissions = 0;
// Adicionar permissão
public function grant($permission) {
$this->permissions |= $permission;
}
// Remover permissão
public function revoke($permission) {
$this->permissions &= ~$permission;
}
// Verificar permissão
public function has($permission) {
return ($this->permissions & $permission) === $permission;
}
// Alternar permissão (toggle)
public function toggle($permission) {
$this->permissions ^= $permission;
}
public function getPermissions() {
return $this->permissions;
}
}
// Uso
$user = new Permissions();
// Conceder leitura e escrita
$user->grant(Permissions::READ);
$user->grant(Permissions::WRITE);
echo "Permissões: " . $user->getPermissions() . "\n"; // 3 (0011)
// Verificar permissões
var_dump($user->has(Permissions::READ)); // true
var_dump($user->has(Permissions::DELETE)); // false
// Remover escrita
$user->revoke(Permissions::WRITE);
var_dump($user->has(Permissions::WRITE)); // false
// Alternar execução
$user->toggle(Permissions::EXECUTE);
var_dump($user->has(Permissions::EXECUTE)); // true
// Saída esperada
// Permissões: 3
// bool(true)
// bool(false)
// bool(false)
// bool(true)
🎮 Exemplo Prático: Flags de Estado
<?php
class TaskFlags {
const PENDING = 1; // 0001
const IN_PROGRESS = 2; // 0010
const COMPLETED = 4; // 0100
const ARCHIVED = 8; // 1000
const URGENT = 16; // 10000
private $flags = 0;
public function setFlag($flag) {
$this->flags |= $flag;
}
public function clearFlag($flag) {
$this->flags &= ~$flag;
}
public function hasFlag($flag) {
return ($this->flags & $flag) !== 0;
}
public function getStatus() {
$status = [];
if ($this->hasFlag(self::PENDING)) $status[] = 'Pendente';
if ($this->hasFlag(self::IN_PROGRESS)) $status[] = 'Em Progresso';
if ($this->hasFlag(self::COMPLETED)) $status[] = 'Completo';
if ($this->hasFlag(self::ARCHIVED)) $status[] = 'Arquivado';
if ($this->hasFlag(self::URGENT)) $status[] = 'Urgente';
return implode(', ', $status);
}
}
$task = new TaskFlags();
$task->setFlag(TaskFlags::IN_PROGRESS);
$task->setFlag(TaskFlags::URGENT);
echo $task->getStatus(); // "Em Progresso, Urgente"
// Saída esperada
// Em Progresso, Urgente
🎮 Exemplo Prático: Otimização de Multiplicação/Divisão por Potências de 2
<?php
// Multiplicação eficiente por potências de 2
function multiplyBy8($n) {
return $n << 3; // Mais rápido que $n * 8
}
// Divisão eficiente por potências de 2
function divideBy4($n) {
return $n >> 2; // Mais rápido que (int)($n / 4)
}
echo multiplyBy8(5); // 40
echo divideBy4(20); // 5
// Saída esperada
// 405
⚡ Truques Rápidos
<?php
// Verificar se número é par
$isEven = ($n & 1) === 0;
// Verificar se número é ímpar
$isOdd = ($n & 1) === 1;
// Multiplicar por 2
$double = $n << 1;
// Dividir por 2 (arredonda para baixo)
$half = $n >> 1;
// Trocar sinal (negativo <-> positivo)
$opposite = ~$n + 1;
// Verificar se número é potência de 2
$isPowerOf2 = ($n > 0) && (($n & ($n - 1)) === 0);
// Obter bit em posição específica (0-indexed)
function getBit($num, $position) {
return ($num >> $position) & 1;
}
// Setar bit em posição específica
function setBit($num, $position) {
return $num | (1 << $position);
}
// Limpar bit em posição específica
function clearBit($num, $position) {
return $num & ~(1 << $position);
}
� Bitwise no Core do PHP
O próprio PHP utiliza operações bitwise extensivamente em suas funcionalidades internas! Isso demonstra que bitwise não é apenas teoria acadêmica — é uma técnica profissional amplamente adotada.
1. Error Reporting (error_reporting())
A função error_reporting() usa bitwise para controlar quais tipos de erros devem ser reportados.
Constantes de Erro do PHP
<?php
// Principais constantes (todas são potências de 2)
E_ERROR = 1 // 0000 0001
E_WARNING = 2 // 0000 0010
E_PARSE = 4 // 0000 0100
E_NOTICE = 8 // 0000 1000
E_CORE_ERROR = 16 // 0001 0000
E_CORE_WARNING = 32 // 0010 0000
E_COMPILE_ERROR = 64 // 0100 0000
E_COMPILE_WARNING = 128 // 1000 0000
E_USER_ERROR = 256 // ... e assim por diante
E_USER_WARNING = 512
E_USER_NOTICE = 1024
E_STRICT = 2048
E_RECOVERABLE_ERROR = 4096
E_DEPRECATED = 8192
E_USER_DEPRECATED = 16384
E_ALL = 32767 // Todos os bits setados
Exemplos Práticos
<?php
// ✅ Reportar APENAS erros e warnings
error_reporting(E_ERROR | E_WARNING);
// ✅ Reportar TUDO
error_reporting(E_ALL);
// ✅ Reportar tudo EXCETO notices
error_reporting(E_ALL & ~E_NOTICE);
// ✅ Reportar tudo EXCETO notices e deprecations
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
// ✅ Desligar todos os erros
error_reporting(0);
// ✅ Adicionar E_STRICT ao nível atual
error_reporting(error_reporting() | E_STRICT);
// ✅ Remover E_WARNING do nível atual
error_reporting(error_reporting() & ~E_WARNING);
Como Funciona Internamente
<?php
// Exemplo: E_ALL & ~E_NOTICE
//
// E_ALL = 32767 = 0111 1111 1111 1111 (todos os bits)
// E_NOTICE = 8 = 0000 0000 0000 1000
// ~E_NOTICE = = 1111 1111 1111 0111 (NOT inverte os bits)
//
// E_ALL & ~E_NOTICE = 0111 1111 1111 0111 (tudo exceto NOTICE)
📖 Referência: PHP Manual - error_reporting()
2. Permissões de Arquivo (chmod, fileperms)
As permissões Unix/Linux usam bitwise para representar Read, Write e Execute.
<?php
// Permissões Unix (em octal, mas são bits)
// 0755 = rwxr-xr-x
//
// Estrutura: Owner | Group | Others
// rwx | r-x | r-x
// 111 | 101 | 101
// 7 | 5 | 5
// Constantes de verificação de permissão
// (usadas internamente pelo PHP)
$isReadable = 0x0004; // 0000 0100
$isWritable = 0x0002; // 0000 0010
$isExecutable = 0x0001; // 0000 0001
// Verificar permissões
$perms = fileperms('/path/to/file');
if ($perms & 0x0100) { // Bit de execução do owner
echo "Owner pode executar\n";
}
if ($perms & 0x0080) { // Bit de escrita do owner
echo "Owner pode escrever\n";
}
// Setar permissões combinadas
chmod('/path/to/file', 0755); // rwxr-xr-x
📖 Referência:
3. Funções de Filtro (filter_var, filter_input)
A extensão Filter usa flags bitwise para combinar opções de validação.
<?php
// Flags podem ser combinadas com OR
$options = FILTER_FLAG_ALLOW_OCTAL | FILTER_FLAG_ALLOW_HEX;
$number = filter_var('0xFF', FILTER_VALIDATE_INT, [
'flags' => $options
]);
// Flags de validação de URL
$url = filter_var($input, FILTER_VALIDATE_URL, [
'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
]);
// Flags de sanitização
$email = filter_var($input, FILTER_SANITIZE_EMAIL, [
'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH
]);
📖 Referência:
4. Opções de Stream Context (stream_context_create)
<?php
// Flags para abertura de arquivos
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'Accept: application/json'
]
]);
// file_get_contents com flags
$data = file_get_contents(
'https://api.example.com/data',
false, // use_include_path
$context,
0, // offset
1024 // maxlen
);
📖 Referência: PHP Manual - Stream Context
5. JSON Encode/Decode Options
<?php
// Combinar múltiplas opções JSON
$json = json_encode($data,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_UNICODE |
JSON_UNESCAPED_SLASHES
);
// Verificar se uma flag específica está ativa
$options = JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK;
if ($options & JSON_PRETTY_PRINT) {
echo "Pretty print está ativo\n";
}
// Remover uma flag
$options = $options & ~JSON_NUMERIC_CHECK;
📖 Referência:
6. PDO Fetch Modes
<?php
// Combinar estilos de fetch
$stmt = $pdo->query('SELECT * FROM users');
// Fetch com múltiplas opções
$result = $stmt->fetch(
PDO::FETCH_ASSOC | PDO::FETCH_PROPS_LATE
);
// Opções disponíveis:
// PDO::FETCH_ASSOC
// PDO::FETCH_NUM
// PDO::FETCH_BOTH
// PDO::FETCH_OBJ
// PDO::FETCH_LAZY
// etc.
📖 Referência: PHP Manual - PDO Constants
7. File Opening Modes (fopen)
<?php
// Flags internas do fopen (abstraídas pela string mode)
// Internamente o PHP usa bitwise:
// O_RDONLY = 0x0000
// O_WRONLY = 0x0001
// O_RDWR = 0x0002
// O_CREAT = 0x0040
// O_EXCL = 0x0080
// O_TRUNC = 0x0200
// O_APPEND = 0x0400
// Quando você faz:
$fp = fopen('file.txt', 'r+');
// Internamente: O_RDWR
$fp = fopen('file.txt', 'w');
// Internamente: O_WRONLY | O_CREAT | O_TRUNC
📖 Referência: PHP Manual - fopen()
8. SPL File Flags
<?php
// SplFileObject usa flags bitwise
$file = new SplFileObject('data.csv');
$file->setFlags(
SplFileObject::READ_CSV |
SplFileObject::SKIP_EMPTY |
SplFileObject::DROP_NEW_LINE
);
// Flags disponíveis:
// SplFileObject::READ_CSV
// SplFileObject::READ_AHEAD
// SplFileObject::SKIP_EMPTY
// SplFileObject::DROP_NEW_LINE
📖 Referência: PHP Manual - SplFileObject
9. Regular Expressions (PCRE) Flags
<?php
// Flags PCRE podem ser combinadas
$pattern = '/pattern/i'; // i = case-insensitive
// Ou usando preg_match com flags
preg_match(
'/pattern/',
$subject,
$matches,
PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL
);
// Flags disponíveis:
// PREG_OFFSET_CAPTURE
// PREG_UNMATCHED_AS_NULL
// PREG_PATTERN_ORDER
// PREG_SET_ORDER
📖 Referência:
10. DateTime Formats
<?php
// Constantes do DateTime
$date = new DateTime();
echo $date->format(DateTime::ATOM); // 2025-12-01T15:30:00+00:00
echo $date->format(DateTime::COOKIE); // Sunday, 01-Dec-2025 15:30:00 UTC
echo $date->format(DateTime::ISO8601); // 2025-12-01T15:30:00+0000
// Internamente, essas constantes são gerenciadas com flags
📖 Referência: PHP Manual - DateTime
🎯 Por Que o PHP Usa Bitwise?
-
Performance 🚀
- Operações bitwise são as mais rápidas que existem
- Comparações e combinações são instantâneas
-
Economia de Memória 💾
- Um único
intpode armazenar 32 ou 64 flags booleanas - Muito mais eficiente que arrays ou múltiplas variáveis
- Um único
-
API Limpa ✨
- Permite combinar opções de forma intuitiva:
FLAG_A | FLAG_B - Fácil de ler e entender
- Permite combinar opções de forma intuitiva:
-
Retrocompatibilidade 🔄
- Novos flags podem ser adicionados sem quebrar código existente
- Valores antigos continuam funcionando
🎓 Conclusão sobre Bitwise no PHP
Quando você usa error_reporting(E_ALL & ~E_NOTICE), json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ou chmod(), você está usando operações bitwise!
Isso prova que bitwise não é apenas para casos extremos — é uma técnica fundamental usada diariamente por milhões de desenvolvedores PHP, mesmo que indiretamente.
📚 Documentação Oficial:
�📊 Quando Usar Bitwise?
✅ Bons Casos de Uso:
- Sistemas de permissões/flags
- Processamento de dados binários
- Otimizações de performance crítica
- Algoritmos de criptografia
- Compressão de dados
- Máscaras de rede (endereços IP)
❌ Evitar Quando:
- Código precisa ser altamente legível para iniciantes
- Performance não é crítica
- Operações aritméticas normais são mais claras
🎓 Conclusão
Operações bitwise são ferramentas poderosas que permitem:
- Performance: operações extremamente rápidas
- Compactação: armazenar múltiplos valores booleanos em um único integer
- Controle fino: manipulação precisa de dados binários
Embora não sejam necessárias no dia a dia, dominar bitwise expande significativamente seu arsenal de técnicas de programação!