Подсчет файлов на общем диске Windows через Php из Linux

У меня есть файлы с расширением .msg в общей папке Windows, а мой php-сервер - Linux (сервер LAMP). Я пытаюсь написать php-скрипт, который просто подсчитывает количество файлов .msg в общей папке Windows.

Я использую класс smbclient, и вот что я написал:

<?php
require_once ('smbclient.php');
$smbc = new smbclient ('//192.168.10.14/reservations', 'user', 'pass');
$handle = popen ($smbc);
$files = glob($handle . '*.msg');
$filecount = count( $files );
echo $filecount;
?>

Однако я всегда получаю 0 в качестве вывода, но файлов более 200.


person elstiv    schedule 12.02.2015    source источник


Ответы (1)


Вы не можете glob такую ​​ручку. Фактически вы пытаетесь подставить Resource (12)/*.msg, если это фактический ресурс, возвращенный popen (это означает, что smbclient::__toString() должен был вернуть protocol://username:password@host/the/share/url и должен был автоматически зарегистрировать оболочку потока для protocol).

Но даже тогда это не сработает, потому что glob работает только с вещами, существующими в файловой системе (поэтому его нужно будет смонтировать)... Похоже, это также относится и к GlobIterator из SPL.

Как минимум, вам нужно будет просмотреть каждый файл и проверить имя на соответствие вашему шаблону. Поэтому имейте в виду, что любое решение на этом этапе будет несколько медленным в зависимости от сетевого подключения и количества файлов/каталогов в общем ресурсе.

Поскольку я не знаю кода для клиента smb, который вы используете, я приведу пример с одним, который я знаю, как использовать, и это работает. munkie/samba — это клиент PHP SMB и соответствующая оболочка потока для системы smbclient, поэтому вам нужно будет использовать функции файловой системы, которые работайте с потоками, чтобы использовать его:

Использование только PHP (и SPL, который должен быть встроен)

Используя итераторы SPL, мы можем быстро рекурсивно читать каталоги и выполнять поиск по именам файлов. :

// assuming you installed via composer so use its autoloder
$autoloader = require_once('vendor/autoload.php');

use Samba\SambaStreamWrapper;

SambaStreamWrapper::register();

$dir = new RecusrsiveDirectoryIterator(new DirectoryIterator(
    'smb://username:[email protected]/reservations'
));

$finder = new RegexIterator($dir, '#^.+\.msg$#i', RecursiveRegexIterator::MATCH);

$count = 0;

foreach($finder as $match) {
   $count++;
}

echo $count;

Использование ОЧЕНЬ удобного компонента symfony/finder

Компонент symfony/finder упрощает нам задачу и делает ее менее загадочной. В дополнение к поддержке шаблонов поиска globs и регулярных выражений он реализует Countable, поэтому мы можем вызывать $var->count() для получения подсчета вместо того, чтобы зацикливаться на результатах и ​​подсчитывать их вручную (хотя внутренне ему все еще нужно перебирать результат для подсчета). Это также упрощает работу с гораздо более сложными поисковыми запросами. Не похоже, что это поддержка, которая вам нужна в данный момент, но она может пригодиться позже:

// assuming you installed via composer so use its autoloder
$autoloader = require_once('vendor/autoload.php');

use Samba\SambaStreamWrapper;
use Symfony\Component\Finder\Finder;

SambaStreamWrapper::register();

$finder = new Finder();
$finder
    ->files()
    ->name('*.msg')
    ->in('smb://username:[email protected]/reservations');

// YAY Countable!
echo $finder->count();

Другой вариант, который у вас есть, — это фактически смонтировать общий ресурс, а затем использовать glob(), GlobIterator или symfony/finder. Но это может быть немного сложно в зависимости от характера того, для чего вы это используете, и как вы хотите его монтировать... Это было подробно рассмотрено здесь.

Наконец, если это сообщения электронной почты в почтовом ящике, вам, вероятно, гораздо лучше использовать библиотеку/компонент почтового ящика, например Zend_Mail для подключения и подсчета сообщений.

person prodigitalson    schedule 12.02.2015