---
# System prepended metadata

title: "\U0001F4DA Material de Estudo Completo: PHP 8 e Laravel"

---

# 📚 Material de Estudo Completo: PHP 8 e Laravel
## Estilo Banca IDECAN — Concursos Públicos

---

> **Observação:** A banca IDECAN costuma cobrar conceitos teóricos, sintaxe, boas práticas, recursos novos de versão, e diferenças entre versões. Este material cobre os tópicos mais recorrentes com questões no estilo da banca.

---

## SUMÁRIO

1. [PHP 8 — Novidades e Recursos](#1-php-8--novidades-e-recursos)
2. [Tipos e Declarações de Tipo](#2-tipos-e-declarações-de-tipo)
3. [Orientação a Objetos em PHP 8](#3-orientação-a-objetos-em-php-8)
4. [Tratamento de Erros e Exceções](#4-tratamento-de-erros-e-exceções)
5. [PHP 8.1 e 8.2 — Principais Adições](#5-php-81-e-82--principais-adições)
6. [Laravel — Fundamentos](#6-laravel--fundamentos)
7. [Eloquent ORM](#7-eloquent-orm)
8. [Rotas, Controllers e Middleware](#8-rotas-controllers-e-middleware)
9. [Blade Template Engine](#9-blade-template-engine)
10. [Migrations, Seeders e Factories](#10-migrations-seeders-e-factories)
11. [Autenticação e Autorização](#11-autenticação-e-autorização)
12. [Artisan CLI](#12-artisan-cli)
13. [Questões no Estilo IDECAN com Gabarito](#13-questões-no-estilo-idecan-com-gabarito)

---

## 1. PHP 8 — Novidades e Recursos

### 1.1 JIT Compiler (Just In Time)
O PHP 8 introduziu o **compilador JIT**, que converte código PHP em código de máquina nativo em tempo de execução, melhorando o desempenho em operações computacionalmente intensivas.

- O JIT é habilitado via `opcache.jit` no `php.ini`
- Dois modos principais: **Tracing JIT** e **Function JIT**
- Maior ganho em aplicações CPU-bound (processamento numérico)

```ini
; php.ini
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing
```

---

### 1.2 Named Arguments (Argumentos Nomeados)

Permitem passar argumentos para funções usando o **nome do parâmetro**, independente da ordem.

```php
// PHP 8+
function criarUsuario(string $nome, int $idade, string $email) { ... }

criarUsuario(
    email: 'joao@email.com',
    nome: 'João',
    idade: 30
);
```

**Vantagens:**
- Código mais legível
- Possibilidade de pular parâmetros opcionais

---

### 1.3 Match Expression

Substitui o `switch` com sintaxe mais limpa, sem necessidade de `break` e com comparação estrita (`===`).

```php
$status = 2;

$resultado = match($status) {
    1 => 'Ativo',
    2, 3 => 'Pendente',
    4 => 'Inativo',
    default => 'Desconhecido',
};

echo $resultado; // Pendente
```

**Diferenças do `switch`:**
| Característica | `switch` | `match` |
|---|---|---|
| Comparação | Fraca (`==`) | Estrita (`===`) |
| `break` | Necessário | Desnecessário |
| Retorna valor | Não | Sim |
| Fall-through | Sim | Não |

---

### 1.4 Nullsafe Operator (`?->`)

Permite encadear chamadas de métodos/propriedades sem verificar `null` a cada passo.

```php
// Antes do PHP 8
$cidade = null;
if ($user !== null) {
    if ($user->getAddress() !== null) {
        $cidade = $user->getAddress()->getCity();
    }
}

// PHP 8 com Nullsafe
$cidade = $user?->getAddress()?->getCity();
```

---

### 1.5 Union Types

Permite declarar que um parâmetro ou retorno aceita **múltiplos tipos**.

```php
function processar(int|string $valor): int|float {
    return is_string($valor) ? strlen($valor) : $valor * 1.5;
}
```

---

### 1.6 Attributes (Anotações Nativas)

PHP 8 substituiu DocBlocks por **Attributes nativos** para metadados.

```php
#[Attribute]
class Route {
    public function __construct(public string $path) {}
}

#[Route('/home')]
class HomeController {
    // ...
}
```

---

### 1.7 Constructor Property Promotion

Elimina código boilerplate ao declarar e inicializar propriedades no construtor.

```php
// Antes do PHP 8
class Produto {
    public string $nome;
    public float $preco;

    public function __construct(string $nome, float $preco) {
        $this->nome = $nome;
        $this->preco = $preco;
    }
}

// PHP 8 — Constructor Promotion
class Produto {
    public function __construct(
        public string $nome,
        public float $preco,
        private int $estoque = 0
    ) {}
}
```

---

### 1.8 Fibers (PHP 8.1)

Mecanismo de concorrência cooperativa (corrotinas) para execução assíncrona.

```php
$fiber = new Fiber(function (): void {
    $valor = Fiber::suspend('fiber');
    echo "Valor recebido: " . $valor . "\n";
});

$value = $fiber->start();
echo $value . "\n"; // fiber
$fiber->resume('hello');
```

---

## 2. Tipos e Declarações de Tipo

### 2.1 Tipos Escalares
`int`, `float`, `string`, `bool`

### 2.2 Tipos Compostos
- `array`, `callable`, `iterable`
- Union Types: `int|string`
- Intersection Types (PHP 8.1): `Countable&Iterator`

### 2.3 Tipos Especiais
- `void` — função não retorna valor
- `never` (PHP 8.1) — função nunca retorna (lança exceção ou chama `exit`)
- `mixed` — qualquer tipo
- `static` — retorna instância da classe atual

### 2.4 Nullable Types
```php
function buscar(?int $id): ?string {
    if ($id === null) return null;
    return "Item $id";
}
```

---

## 3. Orientação a Objetos em PHP 8

### 3.1 Classes Abstratas vs Interfaces

| Característica | Classe Abstrata | Interface |
|---|---|---|
| Instanciamento direto | Não | Não |
| Pode ter implementação | Sim | Não (só assinaturas) |
| Herança múltipla | Não | Sim (múltiplas interfaces) |
| Visibilidade dos métodos | Qualquer | Sempre `public` |
| Constantes | Sim | Sim |

### 3.2 Traits

Mecanismo para reutilização de código em múltiplas classes.

```php
trait Auditavel {
    public function log(string $msg): void {
        echo "[LOG] $msg\n";
    }
}

class Pedido {
    use Auditavel;
}

$pedido = new Pedido();
$pedido->log('Pedido criado');
```

### 3.3 Enums (PHP 8.1)

```php
enum Status {
    case Ativo;
    case Inativo;
    case Pendente;
}

enum Cor: string {
    case Vermelho = 'red';
    case Azul = 'blue';
}

echo Cor::Vermelho->value; // red
```

### 3.4 Readonly Properties (PHP 8.1)

```php
class Usuario {
    public readonly string $nome;

    public function __construct(string $nome) {
        $this->nome = $nome; // Só pode ser atribuído uma vez
    }
}

$u = new Usuario('João');
$u->nome = 'Maria'; // ERRO! Propriedade readonly
```

---

## 4. Tratamento de Erros e Exceções

### 4.1 Hierarquia de Erros
```
Throwable
├── Error
│   ├── TypeError
│   ├── ValueError
│   ├── ArithmeticError
│   └── ParseError
└── Exception
    ├── RuntimeException
    ├── InvalidArgumentException
    ├── LogicException
    └── ...
```

### 4.2 Try-Catch-Finally

```php
try {
    $resultado = dividir(10, 0);
} catch (DivisionByZeroError $e) {
    echo "Divisão por zero: " . $e->getMessage();
} catch (TypeError $e) {
    echo "Tipo errado: " . $e->getMessage();
} finally {
    echo "Sempre executado";
}
```

### 4.3 Captura múltipla (PHP 8)

```php
catch (InvalidArgumentException | RuntimeException $e) {
    // Trata ambas as exceções
}
```

---

## 5. PHP 8.1 e 8.2 — Principais Adições

### PHP 8.1
- **Enums** (puros e backed)
- **Readonly Properties**
- **Fibers**
- **Intersection Types** (`A&B`)
- **never** return type
- **array_is_list()** — verifica se array é lista
- **Constantes em interfaces** e traits

### PHP 8.2
- **Readonly Classes** — todas as propriedades são readonly
- **DNF Types** (Disjunctive Normal Form): `(A&B)|null`
- **Constantes em traits**
- Depreciação de propriedades dinâmicas (sem declaração)

```php
// PHP 8.2 - Readonly Class
readonly class Ponto {
    public function __construct(
        public float $x,
        public float $y,
    ) {}
}
```

---

## 6. Laravel — Fundamentos

### 6.1 O que é Laravel?

Laravel é um **framework PHP** de código aberto que segue o padrão **MVC (Model-View-Controller)** e utiliza diversas convenções para facilitar o desenvolvimento web.

**Principais Características:**
- Eloquent ORM
- Blade Template Engine
- Artisan CLI
- Sistema de Migrations
- Autenticação integrada
- Sistema de Filas (Queues)
- Eventos e Listeners
- Service Container (IoC)
- Facades

### 6.2 Ciclo de Requisição no Laravel

```
Request HTTP
    → index.php
    → Kernel HTTP (bootstrap)
    → Middleware (pipeline)
    → Router
    → Controller
    → Response
```

### 6.3 Service Container e Service Provider

**Service Container:** Motor de injeção de dependências do Laravel.

```php
// Registrar binding
app()->bind(PagamentoInterface::class, PagamentoPix::class);

// Resolver
$pagamento = app(PagamentoInterface::class);
```

**Service Provider:** Classe responsável por registrar serviços no container.

```php
class AppServiceProvider extends ServiceProvider {
    public function register(): void {
        $this->app->bind(PagamentoInterface::class, PagamentoPix::class);
    }

    public function boot(): void {
        // Após todos os providers registrados
    }
}
```

### 6.4 Facades

Fornecem interface estática para classes no Service Container.

```php
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

Cache::put('chave', 'valor', 3600);
DB::table('usuarios')->get();
Log::info('Usuário autenticado');
```

---

## 7. Eloquent ORM

### 7.1 Definindo um Model

```php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Produto extends Model {
    protected $table = 'produtos'; // opcional se seguir convenção
    protected $primaryKey = 'id';
    public $timestamps = true;

    protected $fillable = ['nome', 'preco', 'descricao'];
    protected $hidden = ['senha'];
    protected $casts = [
        'preco' => 'float',
        'ativo' => 'boolean',
        'criado_em' => 'datetime',
    ];
}
```

### 7.2 Operações CRUD

```php
// Criar
$produto = Produto::create(['nome' => 'Caneta', 'preco' => 2.50]);
// ou
$produto = new Produto();
$produto->nome = 'Caneta';
$produto->save();

// Ler
$produtos = Produto::all();
$produto = Produto::find(1);
$produto = Produto::findOrFail(1); // lança ModelNotFoundException
$produto = Produto::where('preco', '>', 10)->first();

// Atualizar
$produto->preco = 3.00;
$produto->save();
// ou
Produto::where('id', 1)->update(['preco' => 3.00]);

// Deletar
$produto->delete();
Produto::destroy(1);
Produto::destroy([1, 2, 3]);
```

### 7.3 Query Builder

```php
DB::table('produtos')
    ->select('nome', 'preco')
    ->where('ativo', true)
    ->whereIn('categoria_id', [1, 2, 3])
    ->orderBy('preco', 'desc')
    ->limit(10)
    ->get();
```

### 7.4 Relacionamentos Eloquent

```php
// Um para Um (hasOne)
class Usuario extends Model {
    public function perfil(): HasOne {
        return $this->hasOne(Perfil::class);
    }
}

// Um para Muitos (hasMany)
class Categoria extends Model {
    public function produtos(): HasMany {
        return $this->hasMany(Produto::class);
    }
}

// Muitos para Muitos (belongsToMany)
class Produto extends Model {
    public function tags(): BelongsToMany {
        return $this->belongsToMany(Tag::class);
    }
}

// Pertence a (belongsTo)
class Produto extends Model {
    public function categoria(): BelongsTo {
        return $this->belongsTo(Categoria::class);
    }
}
```

### 7.5 Eager Loading (Evita N+1)

```php
// N+1 Problem (ruim)
$produtos = Produto::all();
foreach ($produtos as $produto) {
    echo $produto->categoria->nome; // Query por produto!
}

// Eager Loading (correto)
$produtos = Produto::with('categoria')->get();
$produtos = Produto::with(['categoria', 'tags'])->get();

// Lazy Eager Loading
$produtos->load('categoria');
```

### 7.6 Scopes

```php
class Produto extends Model {
    // Local scope
    public function scopeAtivo(Builder $query): Builder {
        return $query->where('ativo', true);
    }

    public function scopePrecoMinimo(Builder $query, float $preco): Builder {
        return $query->where('preco', '>=', $preco);
    }
}

// Uso
$produtos = Produto::ativo()->precoMinimo(10)->get();
```

### 7.7 Soft Delete

```php
use Illuminate\Database\Eloquent\SoftDeletes;

class Produto extends Model {
    use SoftDeletes;
}

$produto->delete(); // Marca deleted_at, não remove
$produto->forceDelete(); // Remove fisicamente
Produto::withTrashed()->get(); // Inclui deletados
Produto::onlyTrashed()->get(); // Só deletados
$produto->restore(); // Restaura
```

---

## 8. Rotas, Controllers e Middleware

### 8.1 Rotas

```php
// routes/web.php
Route::get('/produtos', [ProdutoController::class, 'index']);
Route::post('/produtos', [ProdutoController::class, 'store']);
Route::get('/produtos/{id}', [ProdutoController::class, 'show']);
Route::put('/produtos/{id}', [ProdutoController::class, 'update']);
Route::delete('/produtos/{id}', [ProdutoController::class, 'destroy']);

// Resource (gera todas as rotas CRUD)
Route::resource('produtos', ProdutoController::class);

// API Resource (sem create e edit)
Route::apiResource('produtos', ProdutoController::class);

// Agrupamento
Route::prefix('admin')->middleware('auth')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'index']);
});

// Nome da rota
Route::get('/home', [HomeController::class, 'index'])->name('home');
// Uso: route('home')
```

### 8.2 Controllers

```php
namespace App\Http\Controllers;

use App\Models\Produto;
use Illuminate\Http\Request;

class ProdutoController extends Controller {

    public function index() {
        $produtos = Produto::paginate(15);
        return view('produtos.index', compact('produtos'));
    }

    public function store(Request $request) {
        $dados = $request->validate([
            'nome' => 'required|string|max:255',
            'preco' => 'required|numeric|min:0',
        ]);

        $produto = Produto::create($dados);
        return redirect()->route('produtos.index')->with('sucesso', 'Produto criado!');
    }
}
```

### 8.3 Middleware

```php
// Criar middleware
php artisan make:middleware VerificarIdade

// App\Http\Middleware\VerificarIdade
public function handle(Request $request, Closure $next): Response {
    if ($request->user()->idade < 18) {
        return redirect('acesso-negado');
    }
    return $next($request);
}

// Registrar em app/Http/Kernel.php
protected $routeMiddleware = [
    'idade' => \App\Http\Middleware\VerificarIdade::class,
];

// Uso na rota
Route::get('/adultos', ...)->middleware('idade');
```

### 8.4 Form Request (Validação)

```php
// php artisan make:request StoreProdutoRequest

class StoreProdutoRequest extends FormRequest {
    public function authorize(): bool {
        return true; // ou lógica de autorização
    }

    public function rules(): array {
        return [
            'nome' => 'required|string|max:255',
            'preco' => 'required|numeric|min:0',
            'email' => 'required|email|unique:usuarios,email',
            'status' => 'in:ativo,inativo',
        ];
    }

    public function messages(): array {
        return [
            'nome.required' => 'O nome é obrigatório.',
        ];
    }
}
```

---

## 9. Blade Template Engine

### 9.1 Sintaxe Básica

```blade
{{-- Comentário Blade --}}

{{-- Exibir variável (escapa HTML) --}}
{{ $nome }}

{{-- Exibir sem escape (perigoso!) --}}
{!! $htmlBruto !!}

{{-- Estruturas de controle --}}
@if($logado)
    Bem-vindo, {{ $usuario->nome }}!
@elseif($visitante)
    Por favor, faça login.
@else
    Acesso restrito.
@endif

@foreach($produtos as $produto)
    <li>{{ $produto->nome }} - R$ {{ $produto->preco }}</li>
@endforeach

@forelse($itens as $item)
    <li>{{ $item->nome }}</li>
@empty
    <p>Nenhum item encontrado.</p>
@endforelse

@for($i = 0; $i < 10; $i++)
    <p>{{ $i }}</p>
@endfor

@while($condicao)
    ...
@endwhile
```

### 9.2 Layouts

```blade
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html>
<head>
    <title>@yield('titulo', 'Padrão')</title>
</head>
<body>
    @include('partials.header')
    
    <main>
        @yield('conteudo')
    </main>

    @stack('scripts')
</body>
</html>

{{-- resources/views/produtos/index.blade.php --}}
@extends('layouts.app')

@section('titulo', 'Lista de Produtos')

@section('conteudo')
    <h1>Produtos</h1>
    @foreach($produtos as $produto)
        <p>{{ $produto->nome }}</p>
    @endforeach
@endsection

@push('scripts')
    <script src="produto.js"></script>
@endpush
```

### 9.3 Componentes Blade (Laravel 7+)

```php
// php artisan make:component Alerta
// App\View\Components\Alerta.php
class Alerta extends Component {
    public function __construct(public string $tipo = 'info') {}
    public function render(): View { return view('components.alerta'); }
}
```

```blade
{{-- resources/views/components/alerta.blade.php --}}
<div class="alerta alerta-{{ $tipo }}">
    {{ $slot }}
</div>

{{-- Uso --}}
<x-alerta tipo="erro">
    Ocorreu um erro!
</x-alerta>
```

---

## 10. Migrations, Seeders e Factories

### 10.1 Migrations

```php
// php artisan make:migration create_produtos_table

public function up(): void {
    Schema::create('produtos', function (Blueprint $table) {
        $table->id(); // bigIncrements('id')
        $table->string('nome', 255);
        $table->text('descricao')->nullable();
        $table->decimal('preco', 8, 2);
        $table->boolean('ativo')->default(true);
        $table->foreignId('categoria_id')->constrained()->cascadeOnDelete();
        $table->timestamps(); // created_at e updated_at
        $table->softDeletes(); // deleted_at
    });
}

public function down(): void {
    Schema::dropIfExists('produtos');
}
```

**Comandos Artisan:**
```bash
php artisan migrate           # Executa migrations pendentes
php artisan migrate:rollback  # Reverte último batch
php artisan migrate:fresh     # Drop + migrate
php artisan migrate:reset     # Rollback de todas
php artisan migrate:status    # Status das migrations
```

### 10.2 Seeders

```php
// php artisan make:seeder ProdutoSeeder

class ProdutoSeeder extends Seeder {
    public function run(): void {
        Produto::factory()->count(50)->create();
        
        Produto::create([
            'nome' => 'Produto Especial',
            'preco' => 99.99,
        ]);
    }
}

// DatabaseSeeder
class DatabaseSeeder extends Seeder {
    public function run(): void {
        $this->call([
            CategoriaSeeder::class,
            ProdutoSeeder::class,
        ]);
    }
}
```

```bash
php artisan db:seed
php artisan db:seed --class=ProdutoSeeder
php artisan migrate:fresh --seed
```

### 10.3 Factories

```php
// php artisan make:factory ProdutoFactory

class ProdutoFactory extends Factory {
    public function definition(): array {
        return [
            'nome' => fake()->words(3, true),
            'descricao' => fake()->paragraph(),
            'preco' => fake()->randomFloat(2, 1, 999),
            'ativo' => fake()->boolean(80), // 80% true
            'categoria_id' => Categoria::factory(),
        ];
    }

    // Estado personalizado
    public function inativo(): static {
        return $this->state(['ativo' => false]);
    }
}

// Uso
Produto::factory()->create();
Produto::factory()->count(10)->create();
Produto::factory()->inativo()->create();
```

---

## 11. Autenticação e Autorização

### 11.1 Autenticação

Laravel oferece pacotes de autenticação prontos:
- **Breeze** — simples, Blade
- **Jetstream** — avançado, Livewire ou Inertia
- **Fortify** — backend headless

```php
// Autenticação manual
if (Auth::attempt(['email' => $email, 'password' => $senha])) {
    return redirect('/dashboard');
}

Auth::login($usuario);
Auth::logout();
$usuario = Auth::user();
Auth::id(); // ID do usuário autenticado
Auth::check(); // bool
Auth::guest(); // !check()
```

### 11.2 Autorização — Gates

```php
// AppServiceProvider
Gate::define('editar-produto', function (User $user, Produto $produto) {
    return $user->id === $produto->user_id;
});

// Uso
Gate::allows('editar-produto', $produto);
Gate::denies('editar-produto', $produto);
$this->authorize('editar-produto', $produto); // Controller
```

### 11.3 Autorização — Policies

```php
// php artisan make:policy ProdutoPolicy --model=Produto

class ProdutoPolicy {
    public function update(User $user, Produto $produto): bool {
        return $user->id === $produto->user_id;
    }

    public function delete(User $user, Produto $produto): bool {
        return $user->isAdmin() || $user->id === $produto->user_id;
    }
}

// Controller
$this->authorize('update', $produto);

// Blade
@can('update', $produto)
    <button>Editar</button>
@endcan

@cannot('delete', $produto)
    <p>Sem permissão</p>
@endcannot
```

---

## 12. Artisan CLI

### 12.1 Comandos Mais Cobrados

```bash
# Gerar arquivos
php artisan make:model Produto -mcrf  # Model, Migration, Controller, Factory, Resource
php artisan make:controller ProdutoController --resource
php artisan make:middleware Autenticar
php artisan make:request StoreProdutoRequest
php artisan make:seeder ProdutoSeeder
php artisan make:factory ProdutoFactory
php artisan make:policy ProdutoPolicy
php artisan make:command EnviarRelatorio
php artisan make:event PedidoCriado
php artisan make:listener EnviarEmailPedido
php artisan make:job ProcessarPagamento
php artisan make:mail BoasVindas
php artisan make:notification PedidoAprovado

# Manutenção
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan optimize       # Combina cache
php artisan optimize:clear

# Informação
php artisan route:list
php artisan tinker         # REPL interativo
php artisan about          # Info do ambiente

# Filas
php artisan queue:work
php artisan queue:listen
php artisan queue:failed
php artisan queue:retry all
```

---

## 13. Questões no Estilo IDECAN com Gabarito

---

### 📋 BLOCO 1 — PHP 8 GERAL

---

**Questão 1**
Sobre o PHP 8, assinale a alternativa CORRETA a respeito do operador `?->` (nullsafe operator):

**A)** Lança uma exceção `NullPointerException` quando a variável é nula.  
**B)** Permite encadear chamadas de métodos retornando `null` caso algum elemento da cadeia seja nulo.  
**C)** Converte automaticamente `null` para `false` antes de avaliar a expressão.  
**D)** Funciona apenas em propriedades, não em chamadas de métodos.  
**E)** É equivalente ao operador `??` (null coalescing), retornando sempre um valor padrão.

**✅ Gabarito: B**

*Justificativa:* O operador `?->` retorna `null` imediatamente se qualquer elemento da cadeia for nulo, sem lançar exceção.

---

**Questão 2**
Analise o código PHP 8 a seguir:

```php
$valor = 5;
$resultado = match($valor) {
    1, 2 => 'Baixo',
    3, 4, 5 => 'Médio',
    6, 7 => 'Alto',
};
echo $resultado;
```

O código produzirá como saída:

**A)** Baixo  
**B)** Alto  
**C)** Médio  
**D)** Erro de sintaxe  
**E)** Null  

**✅ Gabarito: C**

---

**Questão 3**
Assinale a alternativa que apresenta uma característica EXCLUSIVA do `match` em relação ao `switch` no PHP 8:

**A)** O `match` permite usar `break` para sair de um caso.  
**B)** O `match` realiza comparação estrita (===), enquanto o `switch` usa comparação fraca (==).  
**C)** O `match` não precisa de expressão de comparação, funcionando como uma série de `if`.  
**D)** O `match` aceita apenas valores inteiros como casos.  
**E)** O `match` executa todos os casos correspondentes (fall-through automático).

**✅ Gabarito: B**

---

**Questão 4**
Sobre o Constructor Property Promotion no PHP 8, considere:

```php
class Funcionario {
    public function __construct(
        public readonly string $nome,
        private int $salario,
        protected string $cargo = 'Analista'
    ) {}
}
```

É CORRETO afirmar que:

**A)** O código contém erro de sintaxe pois `readonly` não pode ser usado em constructor promotion.  
**B)** A propriedade `$nome` não pode ter seu valor alterado após a criação do objeto.  
**C)** O modificador `protected` em `$cargo` causará erro de execução.  
**D)** O valor padrão `'Analista'` é ignorado pelo PHP ao usar promotion.  
**E)** A propriedade `$salario` será automaticamente declarada como `public`.

**✅ Gabarito: B**

*Justificativa:* `readonly` impede que a propriedade seja modificada após a inicialização.

---

**Questão 5**
Em relação aos **Named Arguments** do PHP 8, qual das seguintes afirmações é INCORRETA?

**A)** Permitem passar argumentos em qualquer ordem, usando o nome do parâmetro.  
**B)** Podem ser combinados com argumentos posicionais, desde que os posicionais venham primeiro.  
**C)** Permitem omitir parâmetros opcionais intermediários.  
**D)** Funcionam com funções nativas do PHP.  
**E)** São obrigatórios quando a função possui mais de 3 parâmetros.

**✅ Gabarito: E**

*Justificativa:* Named Arguments são opcionais e podem ser usados em qualquer função, independente do número de parâmetros.

---

### 📋 BLOCO 2 — ORIENTAÇÃO A OBJETOS

---

**Questão 6**
Sobre **Traits** em PHP, assinale a alternativa CORRETA:

**A)** Uma classe pode usar apenas um Trait por vez.  
**B)** Traits podem ser instanciados diretamente com `new`.  
**C)** Traits permitem reutilização de código em múltiplas classes sem necessidade de herança.  
**D)** Traits não podem conter propriedades, apenas métodos.  
**E)** O uso de Trait substitui completamente a necessidade de interfaces.

**✅ Gabarito: C**

---

**Questão 7**
Os **Enums** do PHP 8.1 permitem dois tipos: puro e backed. Sobre Backed Enums, é CORRETO afirmar que:

**A)** Só aceitam valores do tipo `int`.  
**B)** Aceitam valores `string` ou `int` associados a cada caso.  
**C)** Não implementam a interface `UnitEnum`.  
**D)** Não podem ter métodos definidos.  
**E)** São equivalentes às constantes de classe.

**✅ Gabarito: B**

*Justificativa:* Backed Enums associam `string` ou `int` a cada caso. Ex: `enum Status: string { case Ativo = 'ativo'; }`

---

**Questão 8**
Considere o código:

```php
interface Pagavel {
    public function pagar(float $valor): bool;
}

abstract class FormaPagamento implements Pagavel {
    abstract public function validar(): bool;
    
    public function processar(float $valor): string {
        if ($this->validar()) {
            $this->pagar($valor);
            return 'Pago';
        }
        return 'Falhou';
    }
}
```

Assinale a alternativa CORRETA sobre o código acima:

**A)** Ocorrerá erro pois classes abstratas não podem implementar interfaces.  
**B)** A classe `FormaPagamento` não precisa implementar o método `pagar()` pois é abstrata.  
**C)** O método `processar()` não pode chamar `pagar()` pois este não está implementado na classe abstrata.  
**D)** Ocorrerá erro pois `abstract` e `implements` não podem ser usados simultaneamente.  
**E)** A interface `Pagavel` precisaria ser abstrata para funcionar com `FormaPagamento`.

**✅ Gabarito: B**

*Justificativa:* Classes abstratas podem deixar a implementação dos métodos de interfaces para suas subclasses concretas.

---

### 📋 BLOCO 3 — LARAVEL FUNDAMENTOS

---

**Questão 9**
No Laravel, o padrão arquitetural adotado é o MVC. Sobre os componentes deste padrão no contexto do Laravel, assinale a alternativa CORRETA:

**A)** O Model é responsável por definir as rotas da aplicação.  
**B)** A View contém a lógica de negócio e acesso ao banco de dados.  
**C)** O Controller recebe as requisições, interage com o Model e retorna a View.  
**D)** O Eloquent ORM faz parte exclusivamente da camada View.  
**E)** As migrations são componentes da camada Controller.

**✅ Gabarito: C**

---

**Questão 10**
Sobre o **Service Container** do Laravel, analise as afirmações:

I. O Service Container é responsável pelo gerenciamento de dependências e injeção de dependências.  
II. `app()->bind()` registra uma binding singleton que retorna sempre a mesma instância.  
III. `app()->singleton()` garante que a mesma instância seja retornada a cada resolução.  
IV. O Service Container resolve automaticamente dependências tipadas nos construtores dos Controllers.

Estão CORRETAS:

**A)** I e II apenas  
**B)** I, III e IV apenas  
**C)** II e IV apenas  
**D)** Todas estão corretas  
**E)** I e IV apenas  

**✅ Gabarito: B**

*Justificativa:* `bind()` cria nova instância a cada resolução; `singleton()` retorna sempre a mesma instância. A afirmação II está errada pois descreve `singleton()`, não `bind()`.

---

**Questão 11**
Em relação às **Facades** do Laravel, é CORRETO afirmar que:

**A)** Facades são classes que implementam o padrão Singleton diretamente.  
**B)** Facades fornecem uma interface estática para serviços registrados no Service Container.  
**C)** O uso de Facades é obrigatório no Laravel, substituindo a injeção de dependências.  
**D)** Facades não podem ser testadas unitariamente.  
**E)** Facades acessam diretamente o banco de dados sem passar pelo Eloquent.

**✅ Gabarito: B**

---

### 📋 BLOCO 4 — ELOQUENT E BANCO DE DADOS

---

**Questão 12**
Sobre o **problema N+1** no Eloquent ORM, analise o código:

```php
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->autor->nome;
}
```

Qual alternativa descreve corretamente o problema e a solução?

**A)** O código é eficiente; não há problema.  
**B)** Executa 1 query para `Post::all()` e 1 adicional por post para buscar o autor. A solução é usar `Post::with('autor')->get()`.  
**C)** O código executa apenas 2 queries independentemente do número de posts.  
**D)** O problema é resolvido usando `Post::join('autores')->get()`.  
**E)** O `foreach` causa o problema N+1; a solução é substituí-lo por `each()`.

**✅ Gabarito: B**

---

**Questão 13**
Sobre o **Soft Delete** no Eloquent, assinale a alternativa CORRETA:

**A)** O Soft Delete remove fisicamente o registro, mas mantém um backup em tabela separada.  
**B)** Ao usar a trait `SoftDeletes`, o método `delete()` preenche o campo `deleted_at` com a data atual.  
**C)** Registros com Soft Delete são sempre incluídos nas consultas normais do Eloquent.  
**D)** O método `forceDelete()` restaura um registro previamente deletado.  
**E)** Para usar Soft Delete, é necessário substituir o campo `id` por `uuid`.

**✅ Gabarito: B**

---

**Questão 14**
Considere o seguinte relacionamento Eloquent:

```php
class Pedido extends Model {
    public function itens() {
        return $this->hasMany(ItemPedido::class);
    }
}
```

Qual é o tipo de relacionamento definido e qual coluna de chave estrangeira o Eloquent irá procurar **por convenção** na tabela `item_pedidos`?

**A)** `belongsToMany` — procura `pedidos_id`  
**B)** `hasOne` — procura `pedido_id`  
**C)** `hasMany` — procura `pedido_id`  
**D)** `hasMany` — procura `id_pedido`  
**E)** `belongsTo` — procura `pedidos_id`

**✅ Gabarito: C**

*Justificativa:* `hasMany` define "um para muitos". Por convenção, o Eloquent busca `{nome_singular_do_model}_id`, ou seja, `pedido_id`.

---

### 📋 BLOCO 5 — ROTAS E CONTROLLERS

---

**Questão 15**
No Laravel, ao utilizar `Route::resource('fotos', FotoController::class)`, quais rotas são criadas automaticamente? Assinale a alternativa COMPLETA e CORRETA:

**A)** GET /fotos, POST /fotos, GET /fotos/{foto}, PUT /fotos/{foto}, DELETE /fotos/{foto}  
**B)** GET /fotos, POST /fotos, GET /fotos/create, GET /fotos/{foto}, GET /fotos/{foto}/edit, PUT/PATCH /fotos/{foto}, DELETE /fotos/{foto}  
**C)** Apenas GET e POST para /fotos  
**D)** GET /fotos, POST /fotos, PUT /fotos, DELETE /fotos  
**E)** As mesmas rotas do `apiResource`, porém com suporte a sessões.

**✅ Gabarito: B**

*Justificativa:* `Route::resource` cria 7 rotas: index, create, store, show, edit, update, destroy.

---

**Questão 16**
Sobre **Middleware** no Laravel, qual das seguintes afirmações é CORRETA?

**A)** Middleware só pode ser aplicado globalmente a toda a aplicação.  
**B)** Middleware é executado antes e/ou depois da requisição chegar ao Controller.  
**C)** Middleware não pode redirecionar o usuário, apenas modificar a requisição.  
**D)** O método `handle()` do Middleware deve sempre retornar `true` ou `false`.  
**E)** Middleware é registrado exclusivamente no arquivo `routes/web.php`.

**✅ Gabarito: B**

---

**Questão 17**
Sobre validação com **Form Requests** no Laravel, assinale a alternativa CORRETA:

**A)** O método `authorize()` realiza a validação dos campos do formulário.  
**B)** O método `rules()` define as regras de validação; retornando `false` em `authorize()`, a requisição é bloqueada com HTTP 403.  
**C)** Form Requests não podem personalizar mensagens de erro.  
**D)** As regras de validação só funcionam com dados `POST`.  
**E)** O Form Request ignora campos não listados em `rules()` e os passa ao Controller normalmente.

**✅ Gabarito: B**

---

### 📋 BLOCO 6 — BLADE E MIGRATIONS

---

**Questão 18**
No **Blade Template Engine** do Laravel, qual é a diferença entre `{{ $variavel }}` e `{!! $variavel !!}`?

**A)** Não há diferença; ambos produzem a mesma saída.  
**B)** `{{ }}` executa PHP puro; `{!! !!}` exibe apenas strings.  
**C)** `{{ }}` escapa caracteres HTML (XSS-safe); `{!! !!}` exibe o conteúdo sem escapar.  
**D)** `{!! !!}` é mais eficiente em termos de desempenho.  
**E)** `{{ }}` é usado para comentários; `{!! !!}` para variáveis.

**✅ Gabarito: C**

---

**Questão 19**
Sobre **Migrations** no Laravel, analise as afirmações:

I. O comando `php artisan migrate:rollback` desfaz apenas o último batch de migrations.  
II. O comando `php artisan migrate:fresh` executa rollback de todas as migrations e as executa novamente.  
III. O método `down()` é obrigatório e deve sempre ser o inverso do `up()`.  
IV. Migrations permitem versionamento e controle de alterações no schema do banco de dados.

Estão CORRETAS:

**A)** I, II e IV apenas  
**B)** I e III apenas  
**C)** Todas estão corretas  
**D)** II e IV apenas  
**E)** I, II, III e IV  

**✅ Gabarito: A**

*Justificativa:* O método `down()` não é tecnicamente obrigatório (a migration funcionará sem ele), embora seja boa prática. `migrate:fresh` dropa todas as tabelas e executa `migrate`, não faz rollback.

---

**Questão 20**
No contexto do Laravel, sobre **Seeders** e **Factories**, é CORRETO afirmar:

**A)** Factories são usadas exclusivamente em produção para popular dados reais.  
**B)** Seeders são executados automaticamente em cada migration.  
**C)** Factories geram dados falsos e consistentes para testes e desenvolvimento, usando a biblioteca Faker.  
**D)** Um Seeder não pode chamar outros Seeders.  
**E)** O comando `php artisan db:seed` executa apenas o `DatabaseSeeder` e não aceita a opção `--class`.

**✅ Gabarito: C**

---

### 📋 BLOCO 7 — AUTENTICAÇÃO E ARTISAN

---

**Questão 21**
No sistema de **autorização** do Laravel, qual é a diferença entre **Gates** e **Policies**?

**A)** Gates são usados para autenticação; Policies são usadas para autorização.  
**B)** Gates são closures simples para verificar permissões gerais; Policies são classes organizadas por Model para lógica de autorização mais complexa.  
**C)** Policies substituem completamente os Gates e devem ser sempre preferidas.  
**D)** Gates funcionam apenas em Controllers; Policies funcionam apenas em Views Blade.  
**E)** Gates precisam ser registrados em cada rota; Policies são globais.

**✅ Gabarito: B**

---

**Questão 22**
Sobre o **Artisan CLI** do Laravel, assinale a alternativa CORRETA:

**A)** O comando `php artisan tinker` executa todas as migrations pendentes.  
**B)** O comando `php artisan make:model Produto -m` cria o Model e a Migration correspondente.  
**C)** O comando `php artisan optimize` remove todos os caches da aplicação.  
**D)** O `php artisan route:list` cria todas as rotas RESTful para um recurso.  
**E)** O comando `php artisan serve` inicia o servidor em produção.

**✅ Gabarito: B**

*Justificativa:* A flag `-m` no `make:model` cria também a migration. `tinker` é um REPL; `optimize` gera cache (não remove); `route:list` lista as rotas (não cria); `serve` é apenas para desenvolvimento local.

---

**Questão 23 — QUESTÃO INTEGRADORA**

Um desenvolvedor precisa criar uma API RESTful no Laravel para gerenciar produtos. Analise as seguintes ações realizadas:

1. `php artisan make:model Produto -mcrf`  
2. Definiu `protected $fillable = ['nome', 'preco']` no Model  
3. Usou `Route::apiResource('produtos', ProdutoController::class)`  
4. No controller, usou `Produto::with('categoria')->paginate(15)`  

Sobre as ações acima, assinale a alternativa CORRETA:

**A)** A ação 1 cria Model, Migration, Controller, Factory e Request.  
**B)** A ação 2 define quais campos são protegidos contra atribuição em massa (mass assignment).  
**C)** A ação 3 cria 7 rotas, incluindo as rotas `create` e `edit`.  
**D)** A ação 4 executará N+1 queries ao acessar a categoria de cada produto.  
**E)** A ação 2 deveria usar `$guarded` para permitir atribuição em massa.

**✅ Gabarito: B**

*Justificativa:* `$fillable` define campos **permitidos** para mass assignment. A ação 1 cria Model, Migration, Controller, Resource e Factory (não Request). `apiResource` cria 5 rotas (sem create e edit). O `with('categoria')` resolve o N+1.

---

## 📌 RESUMO DAS REGRAS DE OURO — IDECAN

| Tema | Ponto-Chave |
|---|---|
| `match` vs `switch` | `match` usa `===`, retorna valor, sem `break` |
| Nullsafe `?->` | Retorna `null` se qualquer parte for nula |
| Union Types | `int\|string` — aceita múltiplos tipos |
| Readonly | Só pode ser atribuído uma vez (na inicialização) |
| Traits | Reutilização sem herança; classe pode usar vários |
| Enum (PHP 8.1) | Backed: tem valor `string`/`int`; Puro: só nome |
| Facades | Interface estática para o Service Container |
| `hasMany` | Chave estrangeira: `{modelo}_id` na tabela filha |
| Eager Loading | `with()` evita N+1 |
| Soft Delete | `delete()` → preenche `deleted_at`; `forceDelete()` → remove |
| `Route::resource` | 7 rotas (index, create, store, show, edit, update, destroy) |
| `Route::apiResource` | 5 rotas (sem create e edit) |
| Middleware | Intercepta antes/depois do Controller |
| `{{ }}` vs `{!! !!}` | `{{ }}` escapa HTML; `{!! !!}` não escapa |
| `migrate:fresh` | Dropa tudo + executa migrations |
| `migrate:rollback` | Desfaz último batch |
| Gates vs Policies | Gates: closures; Policies: classes por Model |
| `$fillable` | Permite mass assignment nos campos listados |
| Constructor Promotion | Declara e inicializa propriedade no construtor |

---

*Material elaborado com base nos padrões de cobrança da banca IDECAN para concursos públicos envolvendo PHP 8 e Laravel.*
