2013-10-24 4 views
0

저는 가정용 컴퓨터의 온라인 SFTP 클라이언트로 작동 할 웹 사이트에서 작업하고 있습니다. 내가 지금까지 가지고있는 솔루션은 사이트의 UI를 포함하는 색인 ​​(주) PHP 파일과 phpseclib 인 SFTP 연결 관리자 인 SFTP PHP 편의 클래스입니다. PHP SFTP 명령과 상수 연결

<?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'; 
    } 
} 

?> 

SFTP.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> 

index.php

지금 내가 직면하고있어 문제는 순환 논리로 보이는 중 하나입니다.
  • 내가 계획

    UI

  • 에 그 싱글에
  • 현재 결과를 쿼리를 확인 SFTP하는

    1. 는 단일 연결을 설정 : 내 초기 생각은 다음과 같은 방식으로 작동하는 시스템을 가지고 있었다 서버의 디렉토리에있는 여러 항목을 나타내는 클릭 가능한 행이있는 테이블을 표시합니다. 사용자가 해당 행 중 하나를 클릭하면 디렉토리의 새 항목 목록을 반환하고 그에 따라 UI를 업데이트하기를 원합니다. 이를 달성하기 위해 각 테이블 행에 숨겨진 필드를 추가하여 해당 셀의 목록 이름을 유지하려고했습니다. 셀을 클릭하면 해당 숨겨진 필드의 값을 추출하고 새 디렉터리로 테이블을 다시 설정해야합니다. 그런 다음 화면을 교체하고 새 메시지를 반향 출력하지 않는 문제가 발생합니다.

      따라서, 내 질문은 :

      해당 셀을 클릭하면 SFTP 싱글을 기반으로 테이블을 다시 설정하는 방식으로 각 셀에 관한 디렉토리를 저장하는 가장 좋은 방법은 무엇입니까 새 디렉토리?

      위의 코드에는 여러 가지 시도가 있었기 때문에 새로운 뷰어에게는 거의 이해할 수없는 논리 오류가있을 수 있습니다. 또한, 명확하게하기 위해, 나는 올바른 방향으로 방법 론적 관점을 찾고 있으며 누군가 나를위한 코드를 작성하는 것이 아닙니다.

      미리 감사드립니다.

  • +0

    내가 원하는 복잡성에 따라 * 할 방법이 하나 있다고 생각하지 않습니다. AJAX를 통해 SFTP 클래스를 호출하여 폴더 트리를로드하고 JSON 데이터로 반환합니다. 나머지는 Javascript (jquery 또는 다른 lib가 DOM 수정에 도움이 됨)에 의해 처리됩니다. 따라서 언제든지 폴더를 클릭하면 AJAX 요청이 트리를 가져옵니다 (많은 폴더/파일이있는 경우 2-3 개의 하위 디렉토리가있을 수 있습니다). 또한 자바에서이 트리를 캐시하고 "일부 제한 시간 또는 기타"로직이 충족되면 AJAX 만 호출합니다. – JScoobyCed

    +0

    AJAX 옵션을 탐색했습니다. 내가 겪었던 문제는 SFTP 명령이 AJAX를 통해 실행하는 방법을 파악할 수없는 클래스의 일부로 존재한다는 것입니다 (즉, 싱글 톤에 대한 액세스를 얻고 메서드를 호출 함). 그렇지 않으면, 방금 메서드를 호출하는 일반적인 PHP 스크립트를 작성하면, 이는 싱글 톤 개념을 파괴하고 모든 명령으로 서버에 다시 연결한다는 의미입니다. AJAX를 통해 싱글 톤 클래스에서 메서드를 호출하는 방법을 알고 있습니까? –

    +0

    좋아, 나는 어떻게 든 당신의 대답을 기대하고 있었다. 나는이 상황을 결코 만날 수 없기 때문에 나는 도울 수 없다. 나는 누군가 대답을 기다리고있을거야 :) – JScoobyCed

    답변

    1

    In PHP, the singleton paradigm is considered "bad practice". 참조 심판 : Best practice on PHP singleton classes

    당신의 SFTP 클래스가 실제로 위의 예에서 싱글 로직을 구현하는 표시되지 않지만.

    다음 과제는 웹 페이지를 직접 호출 할 때 전체 웹 페이지가 다시로드된다는 것입니다. 일종의 서버 측 캐싱을 사용하면 현재 아키텍처에서 페이지의 일부분 만 업데이트 할 수있는 방법이 없습니다. 코멘트에서 언급했듯이, AJAX는 이것을하기위한 당신의 도구가 될 것입니다.

    싱글 톤은 PHP에서 웹 서버에 대한 브라우저 호출 사이에 존재하지 않습니다. 브라우저가 웹 서버에 접근 할 때마다 반드시 새로운 SFTP 연결이 생성됩니다. 웹 서버가 요청을 완료 할 때마다 사용중인 SFTP 연결이 파괴됩니다.

    방법론 포인터이 찾고있는 사람이됩니다

    1. 초기 UI를로드 브라우저에서 (뷰를 호출 할 수 있습니다) 페이지 되세요. 최소한 기본 설정 인 을 제공해야 할 수도 있습니다.이 첫 번째 호출에서 100 %로드하면됩니다.
    2. 데이터를 제공하는 다른 페이지를 개발하십시오. 선호하는 것은 json 형식입니다.
    3. 데이터 (서버의 테이블)에 대한 개별 호출을 서버로 다시 보게하는 뷰에 javascript (ajax)가 있습니다.
    4. 페이지를 클릭하면 아약스는 올바른 데이터를 제공하기 위해 올바른 페이지로 개별 호출을 수행 한 다음 UI에서 올바른 요소 인 을 새로 고치거나 업데이트합니다.

    개인적으로 서버 요청 간의 세션 데이터 캐싱을위한 Memcached 팬입니다. 즉, SFTP 서버에서 새로 고쳐야 할 때까지 웹 서버에서 디렉토리 목록을 유지하는 데 사용할 수있는 많은 캐싱 서비스가 있습니다. 당신이 당신의 도전을위한 최적의 캐시 솔루션을 연구로서

    , 그것은 가치있는 동안은 (. 당신은 APC, XCache, eAcceleratorZend 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)); 
    } 
    

    그런 다음 우리는 단지 그것을 여부를 결정, 나는 각 요청을 부트 스트랩, 나는이 캐시 된 데이터를로드 경로에 대한 세션을 확인할 수 있습니다 (우리를 위해 memcached를 간다) 사용자 세션 데이터의 $filePath를 저장 만료되었는지 여부를 확인하고 필요에 따라 새로 고칩니다. 활성 요청이 끝나기 전에 데이터를 파일에 기록하십시오.

    +0

    Ajax를 사용하더라도 매번 새로운 연결을 인스턴스화해야합니다. 또한 서버 디렉토리 목록을받을 때 캐시하는 것이 좋을 것 같습니다 (유용한 아이디어 일 것입니다). –

    +0

    사실, 모든 웹 브라우저 요청은 웹 서버에서 SFTP 서버로의 새로운 연결을 생성합니다. – bubba