link()
A função link() do PHP cria um hard link — uma segunda entrada no sistema de arquivos que aponta para o mesmo inode do arquivo original.
A função link() do PHP cria um hard link — uma segunda entrada no sistema de arquivos que aponta para os mesmos dados em disco de um arquivo existente. Esta página explica o que é um hard link, a sintaxe e o valor de retorno da função, um exemplo completo e executável, como ele difere de um link simbólico e os problemas que podem causar falha.
O que é a Função link()?
link() cria um hard link a partir de um arquivo existente (o destino) para um novo nome (o link). Um hard link não é uma cópia e não é um atalho: é uma segunda entrada de diretório que referencia o mesmo inode — o objeto em disco que armazena os dados e metadados de um arquivo. Como ambos os nomes apontam para o mesmo inode, são completamente intercambiáveis: editar por um nome altera o que se vê pelo outro, e os dados do arquivo só são excluídos quando todos os hard links para ele são removidos.
Duas consequências decorrem diretamente disso:
- Hard links devem residir no mesmo sistema de arquivos (partição) que o destino. Inodes são locais a um sistema de arquivos, portanto não é possível criar hard links entre drives ou pontos de montagem diferentes. Se precisar criar um link entre sistemas de arquivos, use um link simbólico — veja
symlink(). - Geralmente não é possível criar hard links para diretórios. A maioria dos sistemas operacionais proíbe hard links para diretórios para evitar ciclos de referência na árvore do sistema de arquivos.
Sintaxe
link(string $target, string $link): bool| Parâmetro | Descrição |
|---|---|
$target | Caminho para o arquivo existente ao qual você deseja criar um link. |
$link | Caminho do novo hard link a ser criado (não deve existir ainda). |
A função retorna true em caso de sucesso e false em caso de falha, emitindo um E_WARNING quando falha.
Um Exemplo Completo e Executável
Este exemplo cria um arquivo, cria um hard link para ele e prova que ambos os nomes compartilham um inode:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
file_put_contents($target, "Hello hard links\n");
if (link($target, $link)) {
echo "Created hard link\n";
}
echo "Same inode? " . (fileinode($target) === fileinode($link) ? "yes" : "no") . "\n";
echo "Link count: " . stat($target)['nlink'] . "\n";
echo "Read via link: " . file_get_contents($link);
unlink($link); // remove only the new name
echo "After unlink, target still exists? " . (file_exists($target) ? "yes" : "no") . "\n";Saída:
Created hard link
Same inode? yes
Link count: 2
Read via link: Hello hard links
After unlink, target still exists? yesObserve que após link() o contador de links (nlink) é 2 — o inode agora tem dois nomes. Remover um nome com unlink() apenas decrementa esse contador; os dados sobrevivem até o contador chegar a zero. É exatamente por isso que excluir um arquivo com hard link não libera seu espaço em disco se outros hard links ainda existirem.
Tratando Falhas com Elegância
Como link() emite um aviso em caso de falha, no código de produção normalmente se suprime o aviso com @ e se age com base no valor de retorno, ou se verifica o destino antes:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
if (file_exists($link)) {
echo "A file already exists at the link path.\n";
} elseif (@link($target, $link)) {
echo "Hard link created.\n";
} else {
echo "Could not create hard link.\n";
}Razões comuns para link() retornar false:
- O arquivo de destino não existe ou você não tem permissão de leitura para ele.
- Você não tem permissão de escrita no diretório onde o link será criado.
- O caminho do link já existe.
- O destino e o link estão em sistemas de arquivos diferentes.
- O destino é um diretório (não permitido na maioria dos sistemas).
Hard Link vs. Link Simbólico
Hard link (link()) | Link simbólico (symlink()) | |
|---|---|---|
| Aponta para | O mesmo inode (dados) | Um caminho (outro nome de arquivo) |
| Sobrevive à exclusão do original | Sim — os dados permanecem até que todos os links sejam removidos | Não — torna-se um link pendente |
| Pode cruzar sistemas de arquivos | Não | Sim |
| Pode criar link para diretório | Geralmente não | Sim |
| Detectar com | stat()['nlink'] > 1 | is_link() |
Se você precisar verificar se um caminho é um link simbólico ou ler para onde aponta, consulte is_link() e readlink(). Para inspecionar os metadados de um link, use linkinfo().
Quando Usar Isso?
Hard links são úteis para desduplicação e trocas atômicas de arquivos. Ferramentas de backup os utilizam para que arquivos inalterados entre snapshots compartilhem uma única cópia em disco. Scripts de implantação criam um hard link de uma nova versão no lugar e depois renomeiam sobre o nome antigo para que os leitores nunca vejam um arquivo parcialmente escrito. Para necessidades cotidianas de "atalho" que cruzam drives ou apontam para diretórios, use symlink().
Conclusão
link() cria um hard link — um segundo nome para o mesmo inode no mesmo sistema de arquivos. Os dados persistem até que o último hard link seja removido, links não podem cruzar sistemas de arquivos e diretórios geralmente não podem ter hard links. Use o exemplo executável acima para ver o comportamento de inode compartilhado por conta própria, e combine link() com unlink(), symlink() e is_link() para controle total sobre links do sistema de arquivos. Para uma visão geral mais ampla das funções de arquivo, consulte o capítulo PHP Filesystem.