🐘
SFTPconnector_copy.php
Back
📝 Php ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
<?php error_reporting(E_ALL); ini_set('display_errors', 0); ini_set('log_errors', 1); // Start output buffering to catch any unexpected output ob_start(); header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit(0); } class SFTPConnector { private $connection; private $sftp; public function __construct() { // Check if SSH2 extension is available if (!extension_loaded('ssh2')) { throw new Exception('SSH2 extension is not installed'); } } public function connect($host, $port, $username, $password) { try { $this->connection = ssh2_connect($host, $port); if (!$this->connection) { throw new Exception("Could not connect to $host on port $port"); } if (!ssh2_auth_password($this->connection, $username, $password)) { throw new Exception("Authentication failed for user $username"); } $this->sftp = ssh2_sftp($this->connection); if (!$this->sftp) { throw new Exception("Could not initialize SFTP subsystem"); } return true; } catch (Exception $e) { return $e->getMessage(); } } public function listDirectory($path = '.') { try { $handle = opendir("ssh2.sftp://{$this->sftp}$path"); if (!$handle) { throw new Exception("Could not open directory: $path"); } $files = []; while (($file = readdir($handle)) !== false) { if ($file !== '.' && $file !== '..') { $fullPath = rtrim($path, '/') . '/' . $file; $stat = ssh2_sftp_stat($this->sftp, $fullPath); if ($stat !== false) { $files[] = [ 'name' => $file, 'path' => $fullPath, 'size' => $stat['size'], 'modified' => date('Y-m-d H:i:s', $stat['mtime']), 'is_dir' => is_dir("ssh2.sftp://{$this->sftp}$fullPath") ]; } } } closedir($handle); // Sort: directories first, then files usort($files, function($a, $b) { if ($a['is_dir'] && !$b['is_dir']) return -1; if (!$a['is_dir'] && $b['is_dir']) return 1; return strcasecmp($a['name'], $b['name']); }); return $files; } catch (Exception $e) { return false; } } public function uploadFile($localFile, $remotePath) { try { $stream = fopen("ssh2.sftp://{$this->sftp}$remotePath", 'w'); if (!$stream) { throw new Exception("Could not open remote file for writing"); } $data = file_get_contents($localFile); if (fwrite($stream, $data) === false) { throw new Exception("Could not write data to remote file"); } fclose($stream); return true; } catch (Exception $e) { return $e->getMessage(); } } public function downloadFile($remotePath, $localPath) { try { $remoteStream = fopen("ssh2.sftp://{$this->sftp}$remotePath", 'r'); if (!$remoteStream) { throw new Exception("Could not open remote file for reading"); } $localStream = fopen($localPath, 'w'); if (!$localStream) { throw new Exception("Could not open local file for writing"); } while (!feof($remoteStream)) { fwrite($localStream, fread($remoteStream, 8192)); } fclose($remoteStream); fclose($localStream); return true; } catch (Exception $e) { return $e->getMessage(); } } public function deleteFile($remotePath) { try { if (ssh2_sftp_unlink($this->sftp, $remotePath)) { return true; } return "Failed to delete file"; } catch (Exception $e) { return $e->getMessage(); } } public function createDirectory($path) { try { if (ssh2_sftp_mkdir($this->sftp, $path)) { return true; } return "Failed to create directory"; } catch (Exception $e) { return $e->getMessage(); } } public function disconnect() { if ($this->connection) { ssh2_disconnect($this->connection); } } } // Alternative system command approach for servers without SSH2 extension class SystemSFTPConnector { private $host; private $port; private $username; private $password; private $connected = false; public function connect($host, $port, $username, $password) { $this->host = $host; $this->port = $port; $this->username = $username; $this->password = $password; if (!function_exists('exec')) { return 'System commands are disabled on this server'; } // Test SFTP connectivity $testCommand = "echo 'quit' | sftp -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P {$port} {$username}@{$host} 2>&1"; $output = []; $returnCode = null; exec($testCommand, $output, $returnCode); if ($returnCode === 0 || strpos(implode(' ', $output), 'Connected to') !== false) { $this->connected = true; return true; } return 'Cannot connect to SFTP server: ' . implode(' ', $output); } public function listDirectory($path = '/') { if (!$this->connected) { return false; } $scriptFile = tempnam(sys_get_temp_dir(), 'sftp_script'); $script = "cd {$path}\nls -la\nquit\n"; file_put_contents($scriptFile, $script); $command = "sftp -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P {$this->port} -b {$scriptFile} {$this->username}@{$this->host} 2>&1"; $output = []; exec($command, $output); unlink($scriptFile); // Parse the output $files = []; $inListing = false; foreach ($output as $line) { if (strpos($line, 'sftp>') !== false && strpos($line, 'ls') !== false) { $inListing = true; continue; } if ($inListing && strpos($line, 'sftp>') !== false) { break; } if ($inListing && preg_match('/^([drwx-]+)\s+\d+\s+\w+\s+\w+\s+(\d+)\s+(\w+\s+\d+\s+[\d:]+)\s+(.+)$/', $line, $matches)) { $name = $matches[4]; if ($name !== '.' && $name !== '..') { $files[] = [ 'name' => $name, 'path' => rtrim($path, '/') . '/' . $name, 'size' => (int)$matches[2], 'modified' => $matches[3], 'is_dir' => substr($matches[1], 0, 1) === 'd' ]; } } } return $files; } public function deleteFile($remotePath) { if (!$this->connected) { return 'Not connected'; } $scriptFile = tempnam(sys_get_temp_dir(), 'sftp_script'); $script = "rm {$remotePath}\nquit\n"; file_put_contents($scriptFile, $script); $command = "sftp -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P {$this->port} -b {$scriptFile} {$this->username}@{$this->host} 2>&1"; $output = []; exec($command, $output); unlink($scriptFile); if (strpos(implode(' ', $output), 'Removing') !== false || empty(array_filter($output))) { return true; } return 'Delete failed: ' . implode(' ', $output); } public function createDirectory($path) { if (!$this->connected) { return 'Not connected'; } $scriptFile = tempnam(sys_get_temp_dir(), 'sftp_script'); $script = "mkdir {$path}\nquit\n"; file_put_contents($scriptFile, $script); $command = "sftp -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P {$this->port} -b {$scriptFile} {$this->username}@{$this->host} 2>&1"; $output = []; exec($command, $output); unlink($scriptFile); return true; } } // Handle API requests if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input = json_decode(file_get_contents('php://input'), true); if (json_last_error() !== JSON_ERROR_NONE) { ob_clean(); echo json_encode([ 'success' => false, 'message' => 'Invalid JSON input: ' . json_last_error_msg(), ]); exit; } $action = $input['action'] ?? ''; $response = ['success' => false, 'message' => '', 'data' => null]; try { // Try SSH2 extension first, fall back to system commands if (extension_loaded('ssh2')) { $connector = new SFTPConnector(); $connectorType = 'SSH2 Extension'; } else if (function_exists('exec')) { $connector = new SystemSFTPConnector(); $connectorType = 'System Commands'; } else { throw new Exception('Neither SSH2 extension nor system commands are available'); } switch ($action) { case 'connect': $result = $connector->connect( $input['host'] ?? '', $input['port'] ?? 22, $input['username'] ?? '', $input['password'] ?? '' ); if ($result === true) { session_start(); $_SESSION['sftp_connected'] = true; $_SESSION['sftp_config'] = [ 'host' => $input['host'], 'port' => $input['port'] ?? 22, 'username' => $input['username'], 'password' => $input['password'] ]; $response['success'] = true; $response['message'] = "Connected successfully via {$connectorType}"; } else { $response['message'] = $result; } break; case 'list': session_start(); if (isset($_SESSION['sftp_connected'])) { $config = $_SESSION['sftp_config']; // Reconnect for each request if (extension_loaded('ssh2')) { $connector = new SFTPConnector(); } else { $connector = new SystemSFTPConnector(); } $connectResult = $connector->connect( $config['host'], $config['port'], $config['username'], $config['password'] ); if ($connectResult !== true) { $response['message'] = 'Reconnection failed: ' . $connectResult; break; } $files = $connector->listDirectory($input['path'] ?? '/'); if ($files !== false) { $response['success'] = true; $response['data'] = $files; } else { $response['message'] = 'Failed to list directory'; } } else { $response['message'] = 'Not connected to SFTP server'; } break; case 'delete': session_start(); if (isset($_SESSION['sftp_connected'])) { $config = $_SESSION['sftp_config']; if (extension_loaded('ssh2')) { $connector = new SFTPConnector(); } else { $connector = new SystemSFTPConnector(); } $connectResult = $connector->connect( $config['host'], $config['port'], $config['username'], $config['password'] ); if ($connectResult !== true) { $response['message'] = 'Reconnection failed: ' . $connectResult; break; } $result = $connector->deleteFile($input['path'] ?? ''); if ($result === true) { $response['success'] = true; $response['message'] = 'File deleted successfully'; } else { $response['message'] = $result; } } else { $response['message'] = 'Not connected to SFTP server'; } break; case 'create_folder': session_start(); if (isset($_SESSION['sftp_connected'])) { $config = $_SESSION['sftp_config']; if (extension_loaded('ssh2')) { $connector = new SFTPConnector(); } else { $connector = new SystemSFTPConnector(); } $connectResult = $connector->connect( $config['host'], $config['port'], $config['username'], $config['password'] ); if ($connectResult !== true) { $response['message'] = 'Reconnection failed: ' . $connectResult; break; } $result = $connector->createDirectory($input['path'] ?? ''); if ($result === true) { $response['success'] = true; $response['message'] = 'Directory created successfully'; } else { $response['message'] = $result; } } else { $response['message'] = 'Not connected to SFTP server'; } break; case 'disconnect': session_start(); unset($_SESSION['sftp_connected']); unset($_SESSION['sftp_config']); if (isset($connector)) { $connector->disconnect(); } $response['success'] = true; $response['message'] = 'Disconnected successfully'; break; case 'test': $response['success'] = true; $response['message'] = 'SFTP connector responding'; $response['data'] = [ 'ssh2_loaded' => extension_loaded('ssh2'), 'exec_available' => function_exists('exec'), 'system_available' => function_exists('system'), 'shell_exec_available' => function_exists('shell_exec'), 'php_version' => PHP_VERSION, 'time' => date('Y-m-d H:i:s'), 'preferred_method' => extension_loaded('ssh2') ? 'SSH2 Extension' : (function_exists('exec') ? 'System Commands' : 'None Available') ]; break; default: $response['message'] = 'Invalid action: ' . $action; } } catch (Exception $e) { $response['message'] = 'Server error: ' . $e->getMessage(); $response['debug'] = $e->getTraceAsString(); } ob_clean(); echo json_encode($response); } else { ob_clean(); echo json_encode([ 'success' => false, 'message' => 'Only POST requests are allowed', 'debug' => 'Method: ' . $_SERVER['REQUEST_METHOD'] ]); } ?>