Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Cимволические ссылки в Windows

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Функции для работы с символическими ссылками в Windows
Uchkuma
Отправлено: 03 Июня, 2010 - 10:12:09
Post Id



Участник


Покинул форум
Сообщений всего: 1539
Дата рег-ции: Март 2010  
Откуда: Киров


Помог: 6 раз(а)




Работая над своим проектом и решая очередную задачу, я столкнулся необходимостью использования символических ссылок на файлы. Все бы ничего, но для windows php-функции для работы с символическими ссылками не реализованы. На сервере unix, однако разработка ведется в среде windows на Денвере.

Немного погуглив, я обналужил - в винде таки есть поддержка символических ссылок!!! Правда нормальная поддержка симлинков появилась сравнительно недавно, и если у вас WinXP, то вам ничего не светит.

Итак, для работы вам понадобится Windows Vista или старше. ИМХО, конечно, лучше Windows 7. В этих версиях появилась утилита mklink, с помощью которой мы и будем выкручиваться.

Функция symlink для windows:
PHP:
скопировать код в буфер обмена
  1. if(!function_exists('symlink')){
  2. function symlink($file, $link){
  3. //если винда младше висты - неудача
  4. if(preg_match('/^win/i', PHP_OS) AND substr(php_uname(), -4)<6000) return false;
  5. //меняем слеши на виндовый манер
  6. $file = str_replace('/', '\\', $file);
  7. $link = str_replace('/', '\\', $link);
  8.  
  9. if(!exec("mklink $link $file", $out, $err) OR $err!=0) return false;
  10.  
  11. return true;
  12. }
  13. }

Функция is_link для windows:
(функцию называем islink, ибо ф-я is_link есть и в windows-версии php, хотя она и не имеет смысла)
PHP:
скопировать код в буфер обмена
  1. function islink($link){
  2. //если не винда, используем стандартную is_link()
  3. if(!preg_match('/^win/i', PHP_OS)) return is_link($link);
  4. //винда младше висты - неудача
  5. if(substr(php_uname(), -4)<6000) return false;
  6. //меняем слеши на виндовый манер
  7. $link = str_replace('/', '\\', $link);
  8.  
  9. if(!exec("dir $link /a-d", $out, $err) OR !preg_match('/<SYMLINK>/i', utf8_encode($out[5]))) return false; //$out[5] - это нужная нам строка в выводе
  10.  
  11. return true;
  12. }

Необходимая строка вывода, по которой мы определяем является ли файл символической ссылкой, у меня появляется на 5 позиции ($out[5]). Не знаю для всех ли версий интерпретаторов командных строк это будет верно. В крайнем случае можно будет сделать обход по массиву $out.

В функциях мы проверяем операционную систему, на которой работает php и номер сборки windows (6xxx - vista, 7xxx - windows 7).

Надо сказать, что эти функции работают в десятки раз медленнее, чем их юниксовый аналог. Однако для вас это может оказаться не принципиальным. Я, например, провожу эти операции в цикле по списку из 1000 файлов - минуту-две ждать приходится =(

Жду комментарии. Спасибо!

(Отредактировано автором: 11 Июня, 2010 - 15:30:25)

 
 Top
Uchkuma
Отправлено: 11 Июня, 2010 - 10:59:25
Post Id



Участник


Покинул форум
Сообщений всего: 1539
Дата рег-ции: Март 2010  
Откуда: Киров


Помог: 6 раз(а)




Теперь требуется функция, с помощью которой можно будет определить существует файл, на который указывает символическая ссылка, или нет. Некоторый аналог функции linkinfo() для windows. Если есть идеи, пишите!

...

В общем пока назрело только это:
PHP:
скопировать код в буфер обмена
  1. function link_info($link){
  2. //если не винда, запускаем стандартную функцию linkinfo()
  3. if(!preg_match('/^win/i', PHP_OS)) return is_file(readlink($link));
  4. //винда ниже висты - неудача
  5. if(substr(php_uname(), -4)<6000) return false;
  6.  
  7. $fd = @fopen($link, 'r');
  8. //если дескриптор файла открылся, значит он существует
  9. if($fd){
  10. fclose($fd);
  11. return true;
  12. } else {
  13. return false;
  14. }
  15. }

...

Обнаружена странная вещь - функция linkinfo() выдает правду даже при отсутствующем файле, на который указывает ссылка.
Строкузаменил на

(Отредактировано автором: 15 Июня, 2010 - 20:30:42)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Пользовательские функции »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB