Fiz esse script para juntar arquivos de contatos (*.csv) e deixar pronto para envio para o Office 365, ele corrige erros de codificação e também corrige o erro “Nome não está disponível”. Para executá-lo, salve em um arquivo script.php, baixe o PHP 8.3 e rode:
php -q script.php
<?php
$arquivoSaida = 'contatos_final_unificado.csv';
$primeiroArquivo = true;
$emailsProcessados = [];
$fpOut = fopen($arquivoSaida, 'w');
// BOM para Office 365
fprintf($fpOut, chr(0xEF).chr(0xBB).chr(0xBF));
$arquivos = glob("./*.csv");
function ultraFix($text) {
if (empty($text)) return "";
// 1. Dicionário de Prioridade (Trata primeiro os erros MAIS LONGOS)
$map = [
// Erros Triplos (ex: ACESSOCAR)
'Ç' => 'Ç', 'ç' => 'ç', 'ã' => 'ã', 'õ' => 'õ',
'á' => 'á', 'é' => 'é', 'ÃÂ' => 'í', 'ó' => 'ó',
'ú' => 'ú', 'â' => 'â', 'ê' => 'ê', 'ô' => 'ô',
// Erros de codificação que você enviou por último (ex: Tradição)
'çã' => 'ção', 'ç' => 'ç', 'ã' => 'ã', 'ó' => 'ó',
'é' => 'é', 'á' => 'á', 'Ã' => 'í', 'õ' => 'õ',
'â' => 'â', 'ê' => 'ê', 'ô' => 'ô', 'ú' => 'ú',
'Ç' => 'Ç', 'À' => 'À',
// Padrões residuais de caracteres corrompidos por navegadores/sistemas
'Ã?â?¡' => 'Ç', 'Ã?§' => 'ç', 'Ã?£' => 'ã'
];
// Executa a substituição baseada no mapa acima
$text = str_replace(array_keys($map), array_values($map), $text);
// 2. Tenta uma conversão final caso ainda existam bytes de ISO-8859-1 escondidos
// Mas apenas se ainda houver o caractere 'Ã' seguido de algo, indicando erro
if (strpos($text, 'Ã') !== false) {
$attempt = @mb_convert_encoding($text, 'UTF-8', 'ISO-8859-1');
if (mb_check_encoding($attempt, 'UTF-8')) {
$text = $attempt;
}
}
return trim(preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $text));
}
foreach ($arquivos as $arquivo) {
if (basename($arquivo) == $arquivoSaida || strpos($arquivo, '.php') !== false) continue;
if (($handle = fopen($arquivo, "r")) !== FALSE) {
$cabecalho = fgetcsv($handle);
if ($primeiroArquivo && $cabecalho) {
fputcsv($fpOut, $cabecalho);
$primeiroArquivo = false;
}
while (($data = fgetcsv($handle)) !== FALSE) {
$linha = array_map('ultraFix', $data);
// Pega o Display Name (5) e o E-mail (9 ou 25)
$displayName = $linha[5] ?? '';
$email = !empty($linha[9]) ? $linha[9] : ($linha[25] ?? '');
// Se o nome estiver vazio, usa o e-mail como emergência
if (empty($displayName)) {
$displayName = $email;
}
// COPIA Display Name para First Name (índice 1)
$linha[5] = $displayName;
$linha[1] = $displayName;
// Filtro de Duplicados
if (!empty($email)) {
if (isset($emailsProcessados[$email])) continue;
$emailsProcessados[$email] = true;
}
fputcsv($fpOut, $linha);
}
fclose($handle);
}
}
fclose($fpOut);
echo "Arquivo unificado com sucesso e pronto para o OFFICE 365!\n";




