【发布时间】:2018-07-13 13:01:16
【问题描述】:
我有一个 PHP 脚本,可以将本地目录与远程目录同步...
[...]
$ftp = new Ftp('11.222.11.222', 'the_user', 'the_pass');
$ftp->syncFolder('userfiles/project', '/web/userfiles/project', true);
[...]
还有一个班级
class Ftp
{
public $conn;
private $url;
private $user;
private $password;
private $loged;
/**
* Ftp constructor.
* @param $url
* @param $user
* @param $password
* @throws Exception
*/
public function __construct($url, $user, $password)
{
$this->conn = ftp_connect($url);
$this->user = $user;
$this->password = $password;
if ($this->ftp_login($this->user, $this->password)) {
$this->loged = true;
} else {
$this->loged = false;
}
$this->ftp_pasv(true);
}
/**
* @param $func
* @param $a
* @return mixed
* @throws Exception
*/
public function __call($func, $a)
{
if (strstr($func, 'ftp_') !== false && function_exists($func)) {
array_unshift($a, $this->conn);
return call_user_func_array($func, $a);
} else {
if (method_exists($this, $func)) {
return call_user_func_array($func, $a);
} else {
throw new Exception('Undefine Class Function');
}
}
}
/**
* @param $local
* @param $server
* @param $verbose
* @return bool
* @throws Exception
*/
function syncFolder($local, $server, $verbose)
{
if (!$this->loged) {
return false;
}
$this->ftp_chdir($server);
$server_list = $this->ftp_nlist('.');
$local_list = scandir(BASE_PATH . $local);
foreach ($server_list as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$folder = $this->ftp_nlist($item);
if ($folder[0] == '.') {
if (!in_array($item, $local_list)) {
$this->emptyDir($server . '/' . $item, $verbose);
$this->ftp_chdir($server);
} else {
$this->syncFolder($local . '/' . $item, $server . '/' . $item, $verbose);
$this->ftp_chdir($server);
}
} else {
if (!in_array($item, $local_list)) {
if ($this->ftp_delete($item)) {
} else {
}
} else {
$stats = stat(BASE_PATH . $local . '/' . $item);
if ($this->ftp_mdtm($item) < $stats['mtime']) {
if ($this->ftp_put($item, BASE_PATH . $local . '/' . $item, FTP_BINARY)) {
} else {
}
} else {
}
}
}
}
$this->putMissingFilesFromDir($local, $server, $verbose);
$this->ftp_chdir($server);
}
/**
* @param $dir
* @param $verbose
* @return bool
* @throws Exception
*/
function emptyDir($dir, $verbose)
{
if (!$this->loged) {
return false;
}
$this->ftp_chdir($dir);
$server_list = $this->ftp_nlist('.');
foreach ($server_list as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$folder = $this->ftp_nlist($item);
if ($folder[0] == '.') {
$this->emptyDir($dir . '/' . $item, $verbose);
$this->ftp_chdir($dir);
} else {
if ($this->ftp_delete($item)) {
} else {
}
}
}
if ($this->ftp_rmdir($dir)) {
} else {
}
}
/**
* @param $local
* @param $server
* @param $verbose
* @return bool
* @throws Exception
*/
function putMissingFilesFromDir($local, $server, $verbose)
{
if (!$this->loged) {
return false;
}
$this->ftp_chdir($server);
$server_list = $this->ftp_nlist('.');
$local_list = scandir(BASE_PATH . $local);
foreach ($local_list as $item) {
if ($item == '.' || $item == '..') {
continue;
}
if (is_dir(BASE_PATH . $local . '/' . $item)) {
if (!in_array($item, $server_list)) {
$this->ftp_mkdir($item);
}
$this->putMissingFilesFromDir($local . '/' . $item, $server . '/' . $item, $verbose);
$this->ftp_chdir($server);
} else {
if (!in_array($item, $server_list)) {
if ($this->ftp_put($item, BASE_PATH . $local . '/' . $item, FTP_BINARY)) {
} else {
}
}
}
}
}
}
此脚本在浏览器和 Windows 的 CMD 中运行良好,使用以下命令:
C:\php5.6\php.exe -f "D:\www\project\cron\synchro_hosting.php"
但是,当我尝试在计划任务中从批处理文件 运行此脚本时,ftp_connect 函数不执行任何操作。它还在等待什么。
cd /D "D:\www\project\cron\"
"C:\php5.6\php.exe" -f synchro_hosting.php
我正在使用日志文件写入事件(现在已删除以汇总代码)并且代码在 ftp_connect 中停止。
想法?
更新 1:
我尝试从 CMD 运行相同的命令、从 CMD 触发的批处理文件和从计划任务触发的批处理文件,并且与两个第一个选项一起工作正常。当从计划任务中的批处理文件触发时,执行在 ftp_connect 函数中停止。在这三种情况下,执行此操作的 windows 用户是相同的。
C:\php5.6\php.exe -f "D:\www\project\cron\synchro_hosting.php"
我不知道计划任务中的 ftp_connect 问题出在哪里。可能是权限问题?
在 Windows 中还有另一种方法可以反复触发 php 脚本吗?
【问题讨论】:
-
您的 PHP 文件是否在您要更改的目录中? D: 驱动器是本地驱动器还是映射的网络驱动器?
-
我不确定为什么您的批处理文件不只包含您在
cmd.exe提示符下使用的相同命令。如果您特别想规定工作目录,您还可以考虑使用带有/D选项的Start命令。鉴于您提供的信息,批处理文件没有任何问题。然而,在您的“工作”CMD 示例中,工作目录是什么尚未确定。 -
@Squashman:我的 php 文件和我的批处理文件位于同一目录中
www\project\cron\synchro_hosting.php和www\project\cron\cron.bat。 D:驱动器是本地驱动器。 -
@Compo : 好的,这个星期一我会试试你的建议
-
@Compo ...它仍然不起作用
标签: php windows batch-file ftp scheduled-tasks