我正在开发一个网站,作为家用机器的在线SFTP客户端。到目前为止,我所拥有的解决方案是一个索引(主要)php文件,它包含站点的UI,以及一个与phpseclib(SFTP连接管理器)连接的SFTP PHP便利类。
index.php
<?php
require_once "php/Membership.php";
require_once "php/ssh.php";
require_once "php/sftp.php";
$sftp = new SFTP();
error_reporting(E_ALL); // will report any errors your code may have
ini_set("display_errors", 1);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!ATTLIST td fileName CDATA #IMPLIED>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SFTP</title>
<link href="index.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="index.js"></script>
</head>
<body>
<h1 id="welcome">Welcome</h1>
<div id="container">
<div id="content">
<!--SFTP Files-->
<div style="height:1000px; overflow:auto;">
<?php $sftp->set_table(NULL, NULL);?>
</div>
</div>
</div>
</body>
</html>
SFTP.php
<?php
include('Net/SFTP.php');
class SFTP {
private $sftp;
function __construct() {
$this->sftp = new Net_SFTP('99.99.9999.999');
if (!$this->sftp->login('user', 'pwd')) {
exit('Login Failed');
}
echo $this->sftp->pwd() . "\r\n";
}
function set_table($table, $directory) {
if (isset($directory)) {
$this->sftp->chdir($directory);
}
echo '<table id="sftpTable" style="border:1px solid;">';
$result = $this->sftp->nlist();
foreach ($result as $row) {
if (substr($row, 0, 1) != '.') {
echo "<tr>" . "<td class='columnSelect' id=" . $row . "><form method='post' action=''>" . $row . "<input type=\"hidden\" name=\"index\" value=\"" . $row . "\" /></form></td>";
if (strpos($row,'.') !== false)
echo '<td>'. $this->parseBytes($this->sftp->_size($row)) . '</td></tr>';
}
}
echo '</table>';
}
function parseBytes($bytes) {
if ($bytes / 1074000000 >= 1) {
return $bytes / 1074000000 . 'GB';
}
if ($bytes / 1048576 >= 1) {
return $bytes / 1048576 . 'MB';
}
if ($bytes / 1024 >= 1) {
return $bytes / 1024 . 'KB';
}
return $bytes . 'B';
}
}
?>
现在我遇到的问题似乎是循环逻辑。我最初的想法是建立一个以下列方式运作的系统:
我计划显示一个表格,其中可点击的行代表服务器上目录中的不同项目。当用户点击其中一行时,我希望系统返回那个目录的新项目列表,并相应地更新UI。为了实现这一点,我尝试在每个表行中添加一个隐藏字段,以保存该单元格的列表名称。单击单元格后,我需要提取该隐藏字段的值并使用新目录重置该表。然后出现了更换屏幕上的表格而不仅仅是回应新表格的问题。
因此,我的问题是:
以这种方式存储与每个单元格相关的目录的最佳方法是,单击该单元格时,SFTP单例会根据新目录重置一个表吗?
请注意,上述代码可能存在逻辑错误,这可能对新查看者没有多大意义,因为已经进行了许多不同的尝试。另外,要明确的是,我正在寻找正确方向的方法论观点,而不是为我编写代码的人。
提前致谢。
答案 0 :(得分:1)
In PHP, the singleton paradigm is considered "bad practice".
请参阅参考:Best practice on PHP singleton classes
虽然您的SFTP类似乎没有在上面的示例中实际实现单例逻辑。
您的下一个挑战是,当您按原样呼叫网页时,将重新加载整个网页。通过某种服务器端缓存,您当前的架构中无法仅更新页面的一部分。正如评论中所提到的,AJAX将成为您选择的工具。
单身人士根本不存在PHP浏览器对Web服务器的调用。每次浏览器访问Web服务器时,都必须创建新的SFTP连接。每次Web服务器完成请求时,它都会破坏它正在使用的SFTP连接。
您正在寻找的方法指针:
我个人是Memcached的粉丝,用于缓存服务器请求之间的会话数据。话虽这么说,有大量的缓存服务可用于在Web服务器上保存目录列表,直到需要从SFTP服务器刷新。
在为您的挑战研究最佳缓存解决方案时,确保您了解操作码缓存之间的区别是值得的(有许多操作码缓存可供使用。您有APC,XCache ,eAccelerator和Zend Platform。)和数据缓存(会话,变量,用户空间 - 我们建议使用memcached)。
但是,如果您的数据足够大(> 1MB),您通常不希望将其缓存在memcached之类的任何内容中,您可能希望将其缓存到本地文件系统,这是我最近如何做的一个示例这是一个非常大的阵列。
/**
* Will serialize, then write the array to disk, returning the filePath
*
* @param array $array
* @param string $filePath
* @return string
*/
function putCacheData(array $array, $filePath = NULL){
if (empty($filePath)){
$filePath = tempnam(NULL, 'IMPORT');
}
$serializedData = serialize($array);
file_put_contents($filePath, $serializedData);
return $filePath;
}
/**
* Reads the file, unserializes the data, and returns the array.
*
* @param string $filePath
* @return Array|FALSE
*/
function getCacheData($filePath){
$array = array();
if (empty($filePath)){
logmessage("The filepath: [$filepath] is empty!");
return $array;
}
if (! is_file($filePath)){
putImportData($array, $filePath);
return $array;
}
return unserialize( file_get_contents( $filePath ) );
}
然后我们只将$filePath
存储在用户会话数据中(这将转发给我们的memcached),当我引导每个请求时,我可以检查会话中的路径,加载缓存的数据,确定是否存在是否已过期,并可选择刷新它。只需确保在活动请求结束之前将数据写入文件。