🔢 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⁰

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?

  1. Performance 🚀

    • Operações bitwise são as mais rápidas que existem
    • Comparações e combinações são instantâneas
  2. Economia de Memória 💾

    • Um único int pode armazenar 32 ou 64 flags booleanas
    • Muito mais eficiente que arrays ou múltiplas variáveis
  3. API Limpa

    • Permite combinar opções de forma intuitiva: FLAG_A | FLAG_B
    • Fácil de ler e entender
  4. 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!