Dia 5 — Arrays: PHP e MySQL

Informatica · Conteudo · publicado em 02/10/2026
Aula 1

Arrays indexados

Arrays indexados

Array indexado é a lista: os valores ficam na ordem em que foram escritos e o PHP numera as posições sozinho, começando em 0. A forma curta [] é a usada em código moderno; array() é a antiga e continua válida. Serve para qualquer coleção ordenada em que a posição seja o que importa: uma lista de nomes, de ids, de resultados.

Como se usa

$frutas = ['maçã', 'banana', 'laranja'];
$frutas[] = 'uva';            // acrescenta no fim
echo $frutas[count($frutas) - 1];  // o último

$frutas[0] vale 'maçã'. O último índice é sempre count($array) - 1. Índice que não existe devolve null e levanta aviso de *undefined array key*; índice de string ($frutas['nome']) é erro fatal.

As pontas da lista

FunçãoAssinaturaExemplo
countcount(array $array): intcount($frutas) devolve 3
array_pusharray_push(array &$array, mixed ...$valores): intacrescenta dois e devolve a nova quantidade
array_poparray_pop(array &$array): mixeddevolve e remove o último
array_shiftarray_shift(array &$array): mixeddevolve e remove o primeiro
array_unshiftarray_unshift(array &$array, mixed ...$valores): intinsere no início
array_splicearray_splice(array &$array, int $offset, ?int $length = null, mixed ...$substituicao): arrayremove um item a partir do índice 2

As quatro primeiras recebem o array por referência: o argumento precisa ser uma variável, não um literal nem o resultado de outra função, e a mudança é vista por quem chamou. array_pop, array_shift e array_splice renumeram a lista depois de remover.

Juntar listas

FunçãoAssinaturaExemplo
array_mergearray_merge(array ...$arrays): arrayarray_merge($a, $b, [6])
array_combinearray_combine(array $chaves, array $valores): arrayarray_combine(['id','nome'], [1,'Ana']) monta um associativo
array_fillarray_fill(int $start, int $count, mixed $value): arrayarray_fill(0, 3, 0) cria três zeros
array_padarray_pad(array $array, int $size, mixed $value): arraycompleta com null até 5 itens
array_is_listarray_is_list(array $array): booldiz se os índices correm de 0 em 1

array_merge devolve sempre um array novo e renumera as chaves numéricas. [5 => 'a'] mesclado com [10 => 'b'] vira [0 => 'a', 1 => 'b']. Para preservar as chaves, use o operador + ou o despread [...$a, ...$b], do PHP 8.1.

Índice escrito à mão ([5 => 'cinco', 10 => 'dez']) cria uma lista com buracos. count() conta os elementos (2), não o maior índice (10), e um for com count() como limite pula posições. Nesse caso o foreach resolve.

Exemplo

<?php
// ============================================================
// AULA 1 - Arrays indexados: a lista, o indice 0 e as pontas
// ============================================================

declare(strict_types=1);

// A forma curta: colchetes. O PHP numera sozinho, comecando em 0.
$frutas = ['maçã', 'banana', 'laranja'];

echo "Lista: " . implode(', ', $frutas) . "\n";
echo "Quantidade (count): " . count($frutas) . "\n";
echo "Indice 0: " . $frutas[0] . "\n";
echo "Ultimo indice (count - 1): " . (count($frutas) - 1) . "\n";
echo "Ultimo item: " . $frutas[count($frutas) - 1] . "\n";
echo "reset devolve o primeiro: " . reset($frutas) . "\n";
echo "end devolve o ultimo: " . end($frutas) . "\n\n";

// Indice que nao existe devolve null e levanta aviso. Com ?? o PHP
// responde null sem aviso nenhum.
echo "Indice 99 (nao existe): ";
var_dump($frutas[99] ?? null);
echo "\n";

// Colchete vazio acrescenta sempre no fim da lista.
$frutas[] = 'uva';
$frutas[] = 'manga';
echo "\nDepois de dois [] = : " . implode(', ', $frutas) . "\n";

// array_push acrescenta varios de uma vez e devolve a nova quantidade.
$total = array_push($frutas, 'abacaxi', 'melancia');
echo "array_push devolveu a nova quantidade: $total\n";

// array_pop remove e devolve o ultimo item.
$ultimo = array_pop($frutas);
echo "array_pop devolveu: $ultimo\n";

// array_shift remove e devolve o primeiro item, reindexando os outros.
$primeiro = array_shift($frutas);
echo "array_shift devolveu: $primeiro\n";
echo "Lista depois das duas remocoes: " . implode(', ', $frutas) . "\n";

// array_unshift devolve varios itens para o comeco da lista.
array_unshift($frutas, 'goiaba', 'abacate');
echo "Com array_unshift no inicio: " . implode(', ', $frutas) . "\n\n";

// array_merge junta listas e devolve um array NOVO, sem mexer nos originais.
$a = [1, 2, 3];
$b = [4, 5];
$junta = array_merge($a, $b, [6]);
echo "array_merge(\$a, \$b, [6]): " . implode(', ', $junta) . "\n";
echo "A lista original \$a continua com " . count($a) . " itens\n";

// array_merge renumera as chaves numericas: o indice 5 vira indice 0.
$esparsa = [5 => 'cinco', 10 => 'dez'];
$renumerada = array_merge($esparsa);
echo "\nChaves depois do merge: " . implode(', ', array_keys($renumerada)) . "\n";

// Com indice escrito a mao, count() conta elementos e nao o maior indice.
echo "count() da lista com buracos: " . count($esparsa) . "\n";
echo "Maior indice da lista com buracos: " . max(array_keys($esparsa)) . "\n";

// array_combine monta um associativo a partir de duas listas.
$campos = ['id', 'nome', 'nota'];
$valores = [1, 'Ana Souza', 8.5];
$registro = array_combine($campos, $valores);
echo "\nRegistro montado com array_combine: " . json_encode($registro, JSON_UNESCAPED_UNICODE) . "\n";

// array_is_list diz se os indices comecam em 0 e correm de 1 em 1.
var_dump(array_is_list($frutas), array_is_list($esparsa));

Saída real

Lista: maçã, banana, laranja
Quantidade (count): 3
Indice 0: maçã
Ultimo indice (count - 1): 2
Ultimo item: laranja
reset devolve o primeiro: maçã
end devolve o ultimo: laranja

Indice 99 (nao existe): NULL


Depois de dois [] = : maçã, banana, laranja, uva, manga
array_push devolveu a nova quantidade: 7
array_pop devolveu: melancia
array_shift devolveu: maçã
Lista depois das duas remocoes: banana, laranja, uva, manga, abacaxi
Com array_unshift no inicio: goiaba, abacate, banana, laranja, uva, manga, abacaxi

array_merge($a, $b, [6]): 1, 2, 3, 4, 5, 6
A lista original $a continua com 3 itens

Chaves depois do merge: 0, 1
count() da lista com buracos: 2
Maior indice da lista com buracos: 10

Registro montado com array_combine: {"id":1,"nome":"Ana Souza","nota":8.5}
bool(true)
bool(false)
Aula 2

Arrays associativos

Arrays associativos

Array associativo é o dicionário: em vez de índice automático, cada valor tem uma chave escrita à mão, ligada pelo operador =>. É o formato de um registro, de uma linha de tabela, de um cabeçalho de requisição e de um bloco de configuração. Quando a chave vem de uma variável, é assim que o formulário e o $_GET funcionam.

Como se usa

$aluno = ['id' => 1, 'nome' => 'Ana Souza', 'nota' => 8.5];
$campo = 'nota';
echo $aluno[$campo];              // 8.5
unset($aluno['nota']);            // remove a chave

A chave pode ser string ou int, com acento em string. foreach ($aluno as $chave => $valor) entrega a chave na primeira variável e o valor na segunda, na ordem de inserção.

A diferença que mais gera bug

FunçãoAssinaturaExemplo
issetisset(mixed $variavel, mixed ...$variaveis): boolisset($aluno['bolsa'])
array_key_existsarray_key_exists(string $chave, array $array): boolarray_key_exists('bolsa', $aluno)
getget(mixed $chave, mixed $padrao = null): mixed$aluno['nota'] ?? 0 é o atalho de get
array_key_firstarray_key_first(array $array): int, string ou nullnull se o array estiver vazio
array_key_lastarray_key_last(array $array): int, string ou nullnull se o array estiver vazio

isset devolve false quando o valor é null, mesmo com a chave presente; array_key_exists devolve true. Para saber se o campo existe no registro, use array_key_exists; para saber se tem valor utilizável, isset ou ??.

Combinar dois associativos

FunçãoAssinaturaExemplo
array_mergearray_merge(array ...$arrays): arraychave repetida do segundo sobrescreve a do primeiro
array_replacearray_replace(array $array, array ...$substituicoes): arraysobrescreve pela chave, sem misturar listas e associativos
array_intersect_keyarray_intersect_key(array $array1, array ...$arrays): arraymantém só as chaves que existem em todos
array_diff_keyarray_diff_key(array $array1, array ...$arrays): arraymantém as chaves que não existem nos outros
array_count_valuesarray_count_values(array $array): arrayconta quantas vezes cada valor aparece

array_intersect_key e array_diff_key comparam chaves, nunca valores. Para comparar valores existem array_intersect e array_diff, que preservam as chaves originais.

['nota' => null] com isset dá false; com array_key_exists dá true. O primeiro é checagem de valor, o segundo é de existência. Erro de UPDATE em banco começa quase sempre por confundir os dois.

Exemplo

<?php
// ============================================================
// AULA 2 - Arrays associativos: chave escrita a mao e a seta =>
// ============================================================

declare(strict_types=1);

// A seta => liga a chave ao valor. Depois dela vem o valor, terminado em virgula.
$aluno = [
    'id'     => 1,
    'nome'   => 'Ana Souza',
    'email'  => '[email protected]',
    'cidade' => 'São Paulo',
    'nota'   => 8.5,
    'bolsa'  => null,   // chave presente, valor nulo
];

echo "Nome: {$aluno['nome']}\n";
echo "Cidade: {$aluno['cidade']}\n\n";

// A chave pode ser uma variavel: e assim que o formulario e o $_GET funcionam.
$campo = 'nota';
echo "Acesso pela variavel \$campo: {$aluno[$campo]}\n";
echo "Acesso sem aspas dentro de string: {$aluno['email']}\n\n";

// isset devolve false quando o valor e null, mesmo com a chave presente.
echo "isset(\$aluno['bolsa']): ";
var_dump(isset($aluno['bolsa']));

// array_key_exists olha a chave, e nao o valor.
echo "array_key_exists('bolsa', \$aluno): ";
var_dump(array_key_exists('bolsa', $aluno));
echo "array_key_exists('cidade', \$aluno): ";
var_dump(array_key_exists('cidade', $aluno));
echo "array_key_exists('telefone', \$aluno): ";
var_dump(array_key_exists('telefone', $aluno));

// ?? e o atalho de get com valor padrao.
echo "\nBolsa com padrao 0: " . ($aluno['bolsa'] ?? 0) . "\n";
echo "Telefone com padrao 'nao informado': " . ($aluno['telefone'] ?? 'nao informado') . "\n";

// foreach entrega a chave na primeira variavel e o valor na segunda.
echo "\nChave => valor:\n";
foreach ($aluno as $chave => $valor) {
    $mostrado = is_null($valor) ? 'null' : (string) $valor;
    echo "  $chave => $mostrado\n";
}

echo "\nPrimeira chave: " . array_key_first($aluno) . "\n";
echo "Ultima chave: " . array_key_last($aluno) . "\n";

// unset remove a chave inteira.
$copia = $aluno;
unset($copia['cidade'], $copia['email']);
echo "\nChaves depois do unset: " . implode(', ', array_keys($copia)) . "\n";

// array_merge com chave repetida: o segundo array vence.
$base    = ['nome' => 'Ana', 'nota' => 8.5, 'cidade' => 'Recife'];
$atualiz = ['nota' => 9.0, 'cidade' => 'Olinda'];
$mesclado = array_merge($base, $atualiz);
echo "array_merge: " . json_encode($mesclado, JSON_UNESCAPED_UNICODE) . "\n";

// array_diff_key mantem o que o segundo NAO tem como chave.
$somenteBase = array_diff_key($base, ['cidade' => 'x']);
echo "array_diff_key: " . json_encode($somenteBase, JSON_UNESCAPED_UNICODE) . "\n";

// array_count_values conta repeticoes de valores, usando o valor como chave.
// Só aceita string e int: float vira string, senão a função pula a entrada.
$notas = [8.5, 9.0, 8.5, 7.0, 9.0, 8.5];
echo "\narray_count_values das notas: "
    . json_encode(array_count_values(array_map('strval', $notas))) . "\n";
echo "com float cru:                "
    . json_encode(array_count_values(array_map('intval', array_map('round', $notas)))) . "\n";

Saída real

Nome: Ana Souza
Cidade: São Paulo

Acesso pela variavel $campo: 8.5
Acesso sem aspas dentro de string: [email protected]

isset($aluno['bolsa']): bool(false)
array_key_exists('bolsa', $aluno): bool(true)
array_key_exists('cidade', $aluno): bool(true)
array_key_exists('telefone', $aluno): bool(false)

Bolsa com padrao 0: 0
Telefone com padrao 'nao informado': nao informado

Chave => valor:
  id => 1
  nome => Ana Souza
  email => [email protected]
  cidade => São Paulo
  nota => 8.5
  bolsa => null

Primeira chave: id
Ultima chave: bolsa

Chaves depois do unset: id, nome, nota, bolsa
array_merge: {"nome":"Ana","nota":9,"cidade":"Olinda"}
array_diff_key: {"nome":"Ana","nota":8.5}

array_count_values das notas: {"8.5":3,"9":2,"7":1}
com float cru:                {"9":5,"7":1}
Aula 3

Arrays multidimensionais

Arrays multidimensionais

Array multidimensional é um array que contém outros arrays. A forma mais útil é a tabela em memória: uma lista de linhas associativas com as mesmas chaves, exatamente o que o PDO devolve em fetchAll(PDO::FETCH_ASSOC). Serve para manter o resultado de uma consulta em memória e trabalhar linha a linha sem ir ao banco de novo a cada campo.

Como se usa

$turma = [['id' => 1, 'nome' => 'Ana', 'nota' => 8.5], ['id' => 2, 'nome' => 'Bruno', 'nota' => 6.0]];
echo $turma[0]['nome'];                 // Ana
foreach ($turma as $linha) { /* ... */ }

Índices de linha e de coluna contam separadamente: count($turma) conta linhas e count($turma[0]) conta colunas. Misturar linha indexada com linha associativa no mesmo array é permitido pelo PHP, mas quebra o conceito de coluna.

Acessar colunas inteiras

FunçãoAssinaturaEfeito
array_columnarray_column(array $array, string $chave, ?string $chave_indice = null): arrayextrai uma coluna inteira
array_column com nullarray_column($turma, null, 'id')devolve a linha inteira indexada pelo id
array_walkarray_walk(array &$array, callable $callback, mixed $arg = null): boolaplica a função a cada elemento, com a chave
array_walk_recursivearray_walk_recursive(array &$array, callable $callback, mixed $arg = null): boolo mesmo em arrays aninhados, com o caminho
json_encodejson_encode(mixed $value, int $flags = 0, int $depth = 512): stringserializa tudo num texto, para conferir a estrutura

array_column($turma, 'nome') devolve a lista simples de nomes. Com o terceiro argumento, array_column($turma, 'nome', 'id') monta [1 => 'Ana', 2 => 'Bruno'], o que evita o laço de reindexação. Com null no meio, array_column($turma, null, 'email') monta a tabela inteira indexada por email, e o acesso fica $tabela[$email]['nota'].

Onde parar

SituaçãoO que fazer
Lista de escalares (ids, nomes)array simples, sem chave
Lista de registros com os mesmos camposarray de associativos, a tabela em memória
Arquivo com categorias e itensdois níveis, $dados['categorias'][$i]['itens']
Relação entre duas tabelasduas listas e array_column cruzando as chaves

Quatro níveis ou mais é sinal de que o modelo está ruim, não de que falta sintaxe. A saída é achatar com array_walk_recursive ou voltar para uma consulta ao banco.

Exemplo

<?php
// ============================================================
// AULA 3 - Arrays multidimensionais: a tabela em memoria
// ============================================================

declare(strict_types=1);

// Array de arrays associativos: cada elemento interno e uma linha,
// e as chaves internas sao as colunas. E o formato do fetchAll do PDO.
$turma = [
    ['id' => 1, 'nome' => 'Ana',   'nota' => 8.5, 'cidade' => 'Recife'],
    ['id' => 2, 'nome' => 'Bruno', 'nota' => 6.0, 'cidade' => 'Olinda'],
    ['id' => 3, 'nome' => 'Carla', 'nota' => 9.5, 'cidade' => 'Jaboatao'],
    ['id' => 4, 'nome' => 'Davi',  'nota' => 7.0, 'cidade' => 'Recife'],
];

// count() conta LINHAS aqui e COLUNAS em uma linha.
echo "Linhas: " . count($turma) . "\n";
echo "Colunas da primeira linha: " . count($turma[0]) . "\n";
echo "Nota do Bruno (linha 2, coluna nota): {$turma[1]['nota']}\n\n";

// Nomes das colunas: percorre a primeira linha.
echo "Colunas da tabela: " . implode(' | ', array_keys($turma[0])) . "\n\n";

// foreach entrega a linha inteira; com a posicao, entrega o indice tambem.
echo "Turma completa:\n";
foreach ($turma as $posicao => $linha) {
    printf("  %d) %-6s %-5.1f %s\n", $linha['id'], $linha['nome'], $linha['nota'], $linha['cidade']);
    if ($posicao === 1) {
        echo "     (o foreach com chave tambem entrega a posicao: $posicao)\n";
    }
}

// array_column extrai uma coluna inteira em uma operacao so.
echo "\narray_column 'nome': " . implode(', ', array_column($turma, 'nome')) . "\n";
echo "array_column 'id':   " . implode(', ', array_column($turma, 'id')) . "\n";

// Com o terceiro argumento, a coluna vira chave do resultado: [id => nome].
echo "\narray_column com chave:\n";
foreach (array_column($turma, 'nome', 'id') as $id => $nome) {
    echo "  id $id => $nome\n";
}

// Com null na coluna, devolve a LINHA INTEIRA indexada pela chave informada.
// E o equivalente a guardar o resultado de um SELECT por chave.
$porId = array_column($turma, null, 'id');
echo "\nLinha do id 2: " . json_encode($porId[2], JSON_UNESCAPED_UNICODE) . "\n";

// Tabela auxiliar e o cruzamento de duas listas por chave, sem laco aninhado.
$cidades = [
    'Recife'  => ['uf' => 'PE', 'habitantes' => 4100000],
    'Olinda'  => ['uf' => 'PE', 'habitantes' => 400000],
    'Jaboatao' => ['uf' => 'PE', 'habitantes' => 800000],
];

echo "\nQuantas linhas de cada cidade:\n";
foreach (array_count_values(array_column($turma, 'cidade')) as $cidade => $total) {
    $uf = $cidades[$cidade]['uf'] ?? '??';
    echo "  $cidade ($uf): $total aluno(s)\n";
}

// array_walk recebe a chave e o valor de cada linha, e modifica no lugar.
array_walk($turma, function (array &$linha, int $posicao): void {
    $linha['situacao'] = $linha['nota'] >= 7.0 ? 'aprovado' : 'reprovado';
});

echo "\nSituacao de cada aluno:\n";
foreach ($turma as $linha) {
    echo "  {$linha['nome']}: {$linha['situacao']} ({$linha['nota']})\n";
}

// json_encode serializa a estrutura inteira num texto, util para conferir.
echo "\nEstrutura completa em JSON: " . json_encode($turma, JSON_UNESCAPED_UNICODE) . "\n";

Saída real

Linhas: 4
Colunas da primeira linha: 4
Nota do Bruno (linha 2, coluna nota): 6

Colunas da tabela: id | nome | nota | cidade

Turma completa:
  1) Ana    8.5   Recife
  2) Bruno  6.0   Olinda
     (o foreach com chave tambem entrega a posicao: 1)
  3) Carla  9.5   Jaboatao
  4) Davi   7.0   Recife

array_column 'nome': Ana, Bruno, Carla, Davi
array_column 'id':   1, 2, 3, 4

array_column com chave:
  id 1 => Ana
  id 2 => Bruno
  id 3 => Carla
  id 4 => Davi

Linha do id 2: {"id":2,"nome":"Bruno","nota":6,"cidade":"Olinda"}

Quantas linhas de cada cidade:
  Recife (PE): 2 aluno(s)
  Olinda (PE): 1 aluno(s)
  Jaboatao (PE): 1 aluno(s)

Situacao de cada aluno:
  Ana: aprovado (8.5)
  Bruno: reprovado (6)
  Carla: aprovado (9.5)
  Davi: aprovado (7)

Estrutura completa em JSON: [{"id":1,"nome":"Ana","nota":8.5,"cidade":"Recife","situacao":"aprovado"},{"id":2,"nome":"Bruno","nota":6,"cidade":"Olinda","situacao":"reprovado"},{"id":3,"nome":"Carla","nota":9.5,"cidade":"Jaboatao","situacao":"aprovado"},{"id":4,"nome":"Davi","nota":7,"cidade":"Recife","situacao":"aprovado"}]
Aula 4

Procurar e percorrer arrays

Procurar e percorrer arrays

Procurar dentro de um array é responder a três perguntas: o valor existe, em que posição, e o que fazer com o resto da lista. in_array responde à primeira, array_search à segunda, e as funções de ordenação e fatiamento reorganizam a lista depois do achado.

Como se usa

$frutas = ['maçã', 'banana', 'laranja', 'banana'];
in_array('banana', $frutas, true);       // true
array_search('banana', $frutas, true);   // 1 (a primeira ocorrência)

Procurar valor e procurar chave

FunçãoAssinaturaDevolve
in_arrayin_array(mixed $needle, array $haystack, bool $strict = false): booltrue ou false
array_searcharray_search(mixed $needle, array $haystack, bool $strict = false)a chave achada (int, string) ou false
array_keysarray_keys(array $array, mixed $search_value = null, bool $strict = false): arraytodas as chaves, ou as que têm o valor
array_valuesarray_values(array $array): arraysó os valores, renumerados
array_fliparray_flip(array $array): arrayinverte: valor vira chave
array_key_existsarray_key_exists(string $chave, array $array): booltrue ou false para a chave

Três cuidados: o terceiro argumento true importa (in_array("1", [1, 2]) dá true sem ele, porque converte o tipo); array_search devolve false, não null, então if (array_search(...)) falha quando o índice achado é 0 — compare com !== false; e array_search devolve só a primeira ocorrência, para todas use array_keys($lista, $valor, true).

Ordenar e fatiar

FunçãoAssinaturaO que é reordenado
sortsort(array &$array, int $flags = SORT_REGULAR): boolsó os valores, renumera
asortasort(array &$array, int $flags = SORT_REGULAR): boolmantém cada valor no seu par
ksortksort(array &$array, int $flags = SORT_REGULAR): boolordena pelas chaves
usortusort(array &$array, callable $callback): boolo array inteiro, pelo comparador
array_slicearray_slice(array $array, int $offset, ?int $length = null, bool $preserve_keys = false): arraycópia do trecho, original intacto
array_splicearray_splice(array &$array, int $offset, ?int $length = null, mixed ...$substituicao): arrayremove de verdade e devolve o que saiu
array_chunkarray_chunk(array $array, int $length, bool $preserve_keys = false): arraylista de lotes do tamanho pedido

sort($arquivos) e asort($arquivos) produzem a mesma ordem visual numa lista de nomes, mas sort joga fora as chaves. Com chave que identifica a linha, quem serve é asort. O paginador em memória é array_slice($lista, 0, 10), que corta dez linhas depois de carregar a tabela inteira do banco — o paginador de verdade é LIMIT com OFFSET no SQL.

Exemplo

<?php
// ============================================================
// AULA 4 - Procurar e percorrer arrays: achar, extrair, ordenar, fati ar
// ============================================================

declare(strict_types=1);

$frutas = ['maçã', 'banana', 'laranja', 'banana', 'uva'];
$idades = ['Ana' => 31, 'Bruno' => 25, 'Carla' => 28, 'Davi' => 34];

// in_array responde "o valor existe?". O terceiro argumento true faz
// comparacao estrita: sem ele, "1" e 1 seriam considerados iguais.
echo "Tem banana: " . var_export(in_array('banana', $frutas, true), true) . "\n";
echo "Tem kiwi:    " . var_export(in_array('kiwi', $frutas, true), true) . "\n";
echo "Comparacao frouxa de '1' dentro de [1, 2]: " . var_export(in_array('1', [1, 2]), true) . "\n";
echo "Comparacao estrita de '1' dentro de [1, 2]: " . var_export(in_array('1', [1, 2], true), true) . "\n\n";

// array_search devolve a chave ou false. A primeira ocorrencia apenas.
echo "Indice da primeira banana: " . array_search('banana', $frutas, true) . "\n";
echo "Indice de 'kiwi': " . var_export(array_search('kiwi', $frutas, true), true) . "\n";

// CUIDADO: se o indice achado for 0, o if trata como falso.
$lista = ['ana', 'bruno'];
$achouZero = array_search('ana', $lista, true);
echo "Indice 0 achado, avaliado direto no if: " . var_export((bool) $achouZero, true) . "\n";
echo "Indice 0 comparado com !== false: " . var_export($achouZero !== false, true) . "\n\n";

// array_search devolve so a primeira ocorrencia. Para todas: array_keys.
echo "Indices de todas as bananas: " . implode(', ', array_keys($frutas, 'banana', true)) . "\n";
echo "array_values sem as chaves: " . implode(', ', array_values($idades)) . "\n";

// array_flip inverte: o valor passa a ser chave.
echo "\narray_flip das idades: " . json_encode(array_flip($idades), JSON_UNESCAPED_UNICODE) . "\n";
echo "Nome do mais velho: " . array_search(max($idades), $idades, true) . "\n\n";

// sort reordena os valores e renumera; asort mantem o par chave/valor.
$notas = [8.5, 6.0, 9.5, 7.0];
sort($notas);
echo "sort (crescente):     " . implode(', ', $notas) . "\n";
rsort($notas);
echo "rsort (decrescente):  " . implode(', ', $notas) . "\n";

$porAluno = ['Ana' => 8.5, 'Bruno' => 6.0, 'Carla' => 9.5];
asort($porAluno);
echo "asort por valor:      " . json_encode($porAluno, JSON_UNESCAPED_UNICODE) . "\n";
arsort($porAluno);
echo "arsort por valor:     " . json_encode($porAluno, JSON_UNESCAPED_UNICODE) . "\n";

$porAluno = ['Ana' => 8.5, 'Bruno' => 6.0, 'Carla' => 9.5];
ksort($porAluno);
echo "ksort por chave:      " . json_encode($porAluno, JSON_UNESCAPED_UNICODE) . "\n\n";

// array_slice NAO mexe no original; devolve uma copia do trecho.
$turma = ['Ana', 'Bruno', 'Carla', 'Davi', 'Elena'];
echo "Primeiras tres:    " . implode(', ', array_slice($turma, 0, 3)) . "\n";
echo "Ultimas duas:      " . implode(', ', array_slice($turma, -2)) . "\n";
echo "Do indice 1 ate o fim: " . implode(', ', array_slice($turma, 1, null)) . "\n";
echo "Lista original intacta: " . implode(', ', $turma) . "\n\n";

// array_splice remove de verdade e devolve o que saiu.
$removidos = array_splice($turma, 1, 2);
echo "array_splice removeu: " . implode(', ', $removidos) . "\n";
echo "Lista depois do splice: " . implode(', ', $turma) . "\n\n";

// array_chunk fatia a lista em lotes, util para processar em partes.
echo "Lotes de dois: " . json_encode(array_chunk($turma, 2), JSON_UNESCAPED_UNICODE) . "\n";

// A busca completa, percorrendo a tabela linha a linha quando o valor
// nao esta em coluna nenhuma.
$alunos = [
    ['id' => 1, 'nome' => 'Ana',   'email' => '[email protected]'],
    ['id' => 2, 'nome' => 'Bruno', 'email' => '[email protected]'],
    ['id' => 3, 'nome' => 'Carla', 'email' => '[email protected]'],
];

$termo = '[email protected]';
$achado = null;
foreach ($alunos as $aluno) {
    if ($aluno['email'] === $termo) {
        $achado = $aluno;
        break;
    }
}
echo "\nAchado no foreach: " . json_encode($achado, JSON_UNESCAPED_UNICODE) . "\n";
echo "Com array_column seria: " . json_encode(array_column($alunos, null, 'email')[$termo], JSON_UNESCAPED_UNICODE) . "\n";

Saída real

Tem banana: true
Tem kiwi:    false
Comparacao frouxa de '1' dentro de [1, 2]: true
Comparacao estrita de '1' dentro de [1, 2]: false

Indice da primeira banana: 1
Indice de 'kiwi': false
Indice 0 achado, avaliado direto no if: false
Indice 0 comparado com !== false: true

Indices de todas as bananas: 1, 3
array_values sem as chaves: 31, 25, 28, 34

array_flip das idades: {"31":"Ana","25":"Bruno","28":"Carla","34":"Davi"}
Nome do mais velho: Davi

sort (crescente):     6, 7, 8.5, 9.5
rsort (decrescente):  9.5, 8.5, 7, 6
asort por valor:      {"Bruno":6,"Ana":8.5,"Carla":9.5}
arsort por valor:     {"Carla":9.5,"Ana":8.5,"Bruno":6}
ksort por chave:      {"Ana":8.5,"Bruno":6,"Carla":9.5}

Primeiras tres:    Ana, Bruno, Carla
Ultimas duas:      Davi, Elena
Do indice 1 ate o fim: Bruno, Carla, Davi, Elena
Lista original intacta: Ana, Bruno, Carla, Davi, Elena

array_splice removeu: Bruno, Carla
Lista depois do splice: Ana, Davi, Elena

Lotes de dois: [["Ana","Davi"],["Elena"]]

Achado no foreach: {"id":2,"nome":"Bruno","email":"[email protected]"}
Com array_column seria: {"id":2,"nome":"Bruno","email":"[email protected]"}