link()
La funzione link() di PHP crea un hard link verso un file esistente. Scopri sintassi, parametri, esempi pratici e differenze con i link simbolici.
La funzione PHP link() crea un hard link — una seconda voce nel filesystem che punta agli stessi dati su disco di un file esistente. Questa pagina spiega cosa sia effettivamente un hard link, la sintassi e il valore restituito dalla funzione, un esempio completo ed eseguibile, le differenze rispetto a un link simbolico e le cause più comuni di errore.
Cos'è la Funzione link()?
link() crea un hard link da un file esistente (il target) verso un nuovo nome (il link). Un hard link non è una copia e non è un collegamento: è una seconda voce di directory che fa riferimento allo stesso inode — l'oggetto su disco che memorizza i dati e i metadati di un file. Poiché entrambi i nomi puntano allo stesso inode, sono del tutto intercambiabili: modificare il file attraverso un nome cambia ciò che si vede attraverso l'altro, e i dati vengono eliminati solo quando viene rimosso ogni hard link ad esso.
Da questo derivano direttamente due conseguenze:
- Gli hard link devono risiedere sullo stesso filesystem (partizione) del target. Gli inode sono locali a un filesystem, quindi non è possibile creare hard link tra drive o mount point diversi. Se hai bisogno di collegare tra filesystem diversi, usa invece un link simbolico — vedi
symlink(). - Di solito non è possibile creare hard link alle directory. La maggior parte dei sistemi operativi vieta gli hard link alle directory per evitare cicli di riferimento nell'albero del filesystem.
Sintassi
link(string $target, string $link): bool| Parametro | Descrizione |
|---|---|
$target | Percorso del file esistente a cui collegarsi. |
$link | Percorso del nuovo hard link da creare (non deve esistere già). |
La funzione restituisce true in caso di successo e false in caso di errore, emettendo un E_WARNING quando fallisce.
Un Esempio Completo ed Eseguibile
Questo esempio crea un file, vi crea un hard link e poi dimostra che entrambi i nomi condividono lo stesso 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";Output:
Created hard link
Same inode? yes
Link count: 2
Read via link: Hello hard links
After unlink, target still exists? yesNota che dopo link() il conteggio dei link (nlink) è 2 — l'inode ha ora due nomi. Rimuovere un nome con unlink() decrementa semplicemente quel contatore; i dati sopravvivono finché il contatore non raggiunge zero. È esattamente per questo motivo che eliminare un file con hard link non libera spazio su disco se esistono altri hard link.
Gestire gli Errori in Modo Appropriato
Poiché link() emette un avviso in caso di errore, nel codice di produzione si sopprime tipicamente l'avviso con @ e si agisce sul valore restituito, oppure si verifica prima la destinazione:
<?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";
}Cause comuni per cui link() restituisce false:
- Il file target non esiste oppure mancano i permessi di lettura su di esso.
- Mancano i permessi di scrittura sulla directory in cui verrà creato il link.
- Il percorso del link esiste già.
- Il target e il link si trovano su filesystem diversi.
- Il target è una directory (non consentito sulla maggior parte dei sistemi).
Hard Link vs. Link Simbolico
Hard link (link()) | Link simbolico (symlink()) | |
|---|---|---|
| Punta a | Lo stesso inode (dati) | Un percorso (un altro nome di file) |
| Sopravvive all'eliminazione dell'originale | Sì — i dati rimangono finché tutti i link vengono rimossi | No — diventa un link pendente |
| Può attraversare filesystem | No | Sì |
| Può collegarsi a una directory | Di solito no | Sì |
| Rilevare con | stat()['nlink'] > 1 | is_link() |
Se hai bisogno di sapere se un percorso è un link simbolico, o di leggere dove punta, vedi is_link() e readlink(). Per ispezionare i metadati di un link, usa linkinfo().
Quando Usarlo?
Gli hard link sono utili per la deduplicazione e gli scambi atomici di file. Gli strumenti di backup li usano affinché i file invariati tra gli snapshot condividano una sola copia su disco. Gli script di deployment creano un hard link di una nuova build e poi la rinominano sopra quella vecchia, così i lettori non vedono mai un file scritto parzialmente. Per le normali esigenze di "collegamento rapido" che attraversano drive o puntano a directory, è preferibile usare symlink().
Conclusione
link() crea un hard link — un secondo nome per lo stesso inode sullo stesso filesystem. I dati persistono finché non viene rimosso l'ultimo hard link, i link non possono attraversare filesystem e le directory generalmente non possono essere oggetto di hard link. Usa l'esempio eseguibile sopra per vedere di persona il comportamento con inode condiviso, e abbina link() a unlink(), symlink() e is_link() per un controllo completo sui link del filesystem. Per una panoramica più ampia delle funzioni sui file, vedi il capitolo PHP Filesystem.