如何实现PHP脚本通过SSH连接多台服务器?
Solution: Fetch Raspberry Pi CSV Last Line via SSH in PHP
Looks like you’re already on the right track with your PHP script! Let’s refine it with better error handling, safer data parsing, and clear explanations to ensure it works reliably.
Prerequisites First
Before diving into the code, double-check these critical setup steps to avoid SSH connection issues:
- SSH Key Permissions: The private key file (
/var/www/html/test.rsa) must have strict permissions to be accepted by SSH. Run this on your host server:chmod 600 /var/www/html/test.rsa chown www-data:www-data /var/www/html/test.rsa - Pi SSH Access: Ensure your Pi’s
~/.ssh/authorized_keyscontains the public key matching your private key, and the SSH daemon allows key-based authentication (check/etc/ssh/sshd_configforPubkeyAuthentication yes). - Port & Firewall: Confirm port 97 is open on both the Pi and your host server’s firewall.
Improved PHP Script
Here’s an enhanced version of your script with error handling, safer CSV parsing, and XSS protection:
<?php // Define SSH command to fetch last line of CSV $sshCommand = "ssh -p 97 -i /var/www/html/test.rsa pi@192.168.xxx.xxx 'tail -1 /var/log/playlog.csv'"; // Execute command and capture output/return status $output = []; $returnStatus = 0; exec($sshCommand, $output, $returnStatus); // Check if SSH command succeeded if ($returnStatus !== 0) { echo '<div class="container"><p class="text-danger">Failed to connect to Raspberry Pi or fetch CSV data.</p></div>'; // Optional: Log the error for debugging error_log("SSH command failed with status: $returnStatus"); exit; } // Get the last line (exec returns output as array, last element is our line) $lastLine = end($output); if (empty($lastLine)) { echo '<div class="container"><p class="text-warning">CSV file is empty.</p></div>'; exit; } // Parse CSV line (use str_getcsv for better handling of quoted fields if needed) $csvData = str_getcsv($lastLine); // Ensure we have all expected fields (adjust based on your CSV structure) $expectedFields = 3; if (count($csvData) !== $expectedFields) { echo '<div class="container"><p class="text-warning">Invalid CSV line format.</p></div>'; exit; } // Extract data with XSS protection $timestamp = htmlspecialchars($csvData[0]); $filename = htmlspecialchars($csvData[1]); $statusValue = htmlspecialchars($csvData[2]); // Map status value to readable text (adjust based on your needs) $statusText = match($statusValue) { '-2' => 'Idle', // Add other status codes as needed default => 'Unknown' }; ?> <div class="container"> <table class="table table-striped"> <tr> <th>Timestamp</th> <th>File Name</th> <th>Status</th> </tr> <tr> <td><?= $timestamp ?></td> <td><?= $filename ?></td> <td><?= $statusText ?></td> </tr> </table> </div>
Key Improvements Explained
- Error Handling: We capture the SSH command’s return status to detect connection failures or missing files. This helps you debug issues instead of just getting a blank table.
- Safer CSV Parsing:
str_getcsv()is more reliable thanexplode(',')because it handles edge cases like quoted fields with commas (if your CSV ever uses them). - XSS Protection:
htmlspecialchars()ensures user-supplied data (even from your CSV) doesn’t inject malicious code into your webpage. - Readable Status: The
matchstatement converts numeric status codes into user-friendly text (customize this based on your actual status values).
Debugging Tips
If things aren’t working, test the SSH command directly from your host server’s terminal as the web server user to isolate issues:
sudo -u www-data ssh -p 97 -i /var/www/html/test.rsa pi@192.168.xxx.xxx tail -1 /var/log/playlog.csv
If this command fails, fix the SSH setup first (check key permissions, Pi firewall, etc.) before troubleshooting the PHP script.
内容的提问来源于stack exchange,提问作者Kai
相关产品推荐
相关产品推荐

