通过 Php 从 Linux 计算共享 windows 驱动器上的文件

Counting files on a shared windows drive via Php from Linux

我在 windows 共享文件夹中有扩展名为 .msg 的文件,我的 php 服务器是 Linux(LAMP 服务器)。我正在尝试编写一个 php 脚本,它只计算 Windows 共享文件夹中 .msg 文件的数量。

我正在使用 smbclient class 这是我写的:

<?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 个文件。

你不能 glob 这样的句柄。如果它是由 popen 编辑的实际资源 return,那么您实际上是在尝试 glob Resource (12)/*.msg(这意味着 smbclient::__toString() 需要 return protocol://username:password@host/the/share/url并且需要自动protocol注册一个流包装器)。

但即便如此它也不会工作,因为 glob 只适用于文件系统中存在的东西(因此它需要实际安装)......似乎也是 SPL 的情况 GlobIterator

至少,您需要遍历每个文件并根据您的模式检查名称。因此请记住,此时的任何解决方案都会有些慢,具体取决于网络连接和共享上 files/dirs 的数量。

因为我不知道你正在使用的 smb 客户端的代码,所以我给你举了一个我知道如何使用的例子,它是有效的。 munkie/samba 是一个 PHP SMB 客户端和系统 smbclient 的相应流包装器,因此您需要使用与流一起使用的文件系统函数来利用它:

仅使用 PHP (和应该内置的 SPL)

使用 SPL iterators 我们可以简化递归读取目录和搜索文件名的工作:

// 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:password@192.168.10.14/reservations'
));

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

$count = 0;

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

echo $count;

使用 非常方便 symfony/finder 组件

symfony/finder component 让我们的事情变得更容易一些,也更不那么神秘了。除了支持 glob 和正则表达式搜索模式外,它还实现了 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:password@192.168.10.14/reservations');

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

您在这里的另一个选择是实际挂载共享,然后使用 glob()GlobIteratorsymfony/finder。但这可能会有点棘手,具体取决于您使用它的性质以及您想要如何安装它...... .

最后,如果这些是邮箱中的电子邮件,您最好使用像 Zend_Mail 这样的邮箱 library/component 来连接和计算邮件数量。