W3docs

link()

Функция link() в PHP создаёт жёсткую ссылку — второй элемент файловой системы, указывающий на тот же inode, что и исходный файл.

Функция PHP link() создаёт жёсткую ссылку — второй элемент файловой системы, указывающий на те же данные на диске, что и существующий файл. На этой странице рассказывается, что такое жёсткая ссылка, описывается синтаксис и возвращаемое значение функции, приводится полный рабочий пример, объясняются отличия от символической ссылки, а также разбираются частые причины ошибок.

link() создаёт жёсткую ссылку от существующего файла (цели) к новому имени (ссылке). Жёсткая ссылка — это не копия и не ярлык: это второй элемент каталога, ссылающийся на тот же inode — базовый объект на диске, хранящий данные и метаданные файла. Поскольку оба имени указывают на один и тот же inode, они полностью взаимозаменяемы: редактирование через одно имя отражается при обращении через другое, а данные файла удаляются только после того, как будут удалены все жёсткие ссылки на него.

Из этого непосредственно следуют два вывода:

  • Жёсткие ссылки должны находиться на той же файловой системе (разделе), что и цель. Inode-ы локальны для файловой системы, поэтому создать жёсткую ссылку через диски или точки монтирования невозможно. Если нужно создать ссылку между файловыми системами, используйте символическую ссылку — см. symlink().
  • Жёсткие ссылки на директории обычно запрещены. Большинство операционных систем не разрешают жёсткие ссылки на директории, чтобы предотвратить циклические ссылки в дереве файловой системы.

Синтаксис

link(string $target, string $link): bool
ПараметрОписание
$targetПуть к существующему файлу, на который нужно создать ссылку.
$linkПуть новой жёсткой ссылки (не должна существовать заранее).

Функция возвращает true в случае успеха и false при ошибке, при этом генерируется предупреждение E_WARNING.

Полный рабочий пример

Этот пример создаёт файл, создаёт жёсткую ссылку на него, а затем подтверждает, что оба имени разделяют один 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";

Вывод:

Created hard link
Same inode? yes
Link count: 2
Read via link: Hello hard links
After unlink, target still exists? yes

Обратите внимание: после вызова link() количество ссылок (nlink) равно 2 — inode теперь имеет два имени. Удаление одного имени с помощью unlink() лишь уменьшает этот счётчик; данные сохраняются до тех пор, пока счётчик не достигнет нуля. Именно поэтому удаление файла с жёсткой ссылкой не освобождает дисковое пространство, если остались другие жёсткие ссылки.

Корректная обработка ошибок

Поскольку link() генерирует предупреждение при ошибке, в рабочем коде обычно подавляют предупреждение с помощью @ и проверяют возвращаемое значение, либо заранее проверяют путь назначения:

<?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";
}

Частые причины возврата false функцией link():

  • Целевой файл не существует, или у вас нет прав на его чтение.
  • У вас нет прав на запись в директорию, где будет создана ссылка.
  • Путь для ссылки уже занят.
  • Цель и ссылка находятся на разных файловых системах.
  • Цель является директорией (на большинстве систем запрещено).

Жёсткая ссылка vs. символическая ссылка

Жёсткая ссылка (link())Символическая ссылка (symlink())
Указывает наТот же inode (данные)Путь (другое имя файла)
Переживает удаление оригиналаДа — данные хранятся, пока не удалены все ссылкиНет — становится висячей ссылкой
Может пересекать файловые системыНетДа
Может ссылаться на директориюКак правило, нетДа
Определяется с помощьюstat()['nlink'] > 1is_link()

Если нужно проверить, является ли путь символической ссылкой, или узнать, куда она указывает, см. is_link() и readlink(). Для проверки метаданных ссылки используйте linkinfo().

Когда это использовать?

Жёсткие ссылки удобны для дедупликации и атомарной замены файлов. Инструменты резервного копирования используют их, чтобы неизменённые файлы в разных снапшотах занимали одну копию на диске. Сценарии развёртывания создают жёсткую ссылку на новую версию сборки и переименовывают её поверх старой, чтобы читатели никогда не видели частично записанный файл. Для повседневных задач типа «ярлык», когда нужно пересечь диски или указать на директорию, используйте symlink().

Заключение

link() создаёт жёсткую ссылку — второе имя для того же inode в той же файловой системе. Данные существуют до тех пор, пока не удалена последняя жёсткая ссылка; ссылки не могут пересекать файловые системы, а директории, как правило, не поддерживают жёсткие ссылки. Воспользуйтесь рабочим примером выше, чтобы самостоятельно убедиться в поведении общего inode, и используйте link() вместе с unlink(), symlink() и is_link() для полного управления ссылками в файловой системе. Для более широкого обзора файловых функций см. главу PHP Filesystem.

Практика

Практика
Что создаёт функция link() в PHP?
Что создаёт функция link() в PHP?
Was this page helpful?