# 📚 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.*