How to copy files in PHP using SCP – Step-by-Step

php copy files

Moving files securely between servers is essential for many applications. One of the safest and most efficient ways to do this in PHP is by using SCP, or Secure Copy Protocol. SCP transfers files over SSH, encrypting both the files and login credentials to prevent unauthorized access.

This guide will show you how to use SCP in PHP to transfer files between servers, covering installation, authentication methods, troubleshooting, and best practices.

What You Need

Before setting up SCP in PHP, ensure your environment includes:

  • PHP installed – Run php -v in the terminal to verify.
  • SSH2 extension enabled – Check with phpinfo() or install it if missing.
  • SSH access to the remote server – You’ll need a username, password, or SSH key.

Installing the SSH2 Extension in PHP

The SSH2 extension is required to use SCP functions in PHP. If it’s not installed, follow these steps:

Install SSH2 Extension on Linux

  1. Open a terminal and install the required libraries:
    sudo apt-get install libssh2-1-dev libssh2-php
  2. Enable the extension by adding this to your php.ini file:
    extension=ssh2.so
  3. Restart the web server:
    sudo service apache2 restart

Install SSH2 Extension on Windows

  1. Download the correct DLL for your PHP version from the PECL website.
  2. Move the DLL file to the ext directory inside your PHP installation folder.
  3. Open php.ini and add:
    extension=php_ssh2.dll
  4. Restart your web server.

After installation, confirm that SSH2 is enabled by running php -m | grep ssh2 in the terminal.

Copying Files from Local to Remote Server

Once your PHP environment is set up with the SSH2 extension, you can begin transferring files securely using SCP. This method is useful for deploying updates, backing up data, or automating file transfers between servers. Below is a step-by-step guide on how to send a file from your local machine to a remote server using PHP.

Step 1: Establish an SSH Connection

Use the ssh2_connect() function to connect to the remote server.

// Connect to the remote server using SSH  
$connection = ssh2_connect('remote.server.com', 22);  

// Authenticate using a username and password  
ssh2_auth_password($connection, 'username', 'password');  

Replace 'remote.server.com' with the actual hostname or IP address of the remote server. Use your SSH username and password.

Step 2: Transfer the File

Once connected, use ssh2_scp_send() to upload a file:

// Send a file from the local machine to the remote server using SCP  
ssh2_scp_send($connection, '/local/path/file.txt', '/remote/path/file.txt', 0644);  

// The last parameter (0644) sets file permissions on the remote server  

Change the paths to reflect the correct source and destination. The last parameter (0644) sets file permissions on the remote server.

Copying Files from Remote to Local Server

If you need to download a file from a remote server to your local machine, SCP allows you to securely transfer it over SSH. This is particularly useful when retrieving logs, backups, or configuration files from a remote system. Here’s how you can set up a secure file download using PHP.

Step 1: Establish an SSH Connection

Use ssh2_connect() to connect to the server, just like before.

$connection = ssh2_connect('remote.server.com', 22);
ssh2_auth_password($connection, 'username', 'password');

Ensure the username has permission to access the file you’re retrieving.

Step 2: Download the File

Use ssh2_scp_recv() to copy a file from the remote server to your local machine.

// Retrieve a file from the remote server and save it locally  
ssh2_scp_recv($connection, '/remote/path/file.txt', '/local/path/file.txt');  

Update the paths based on where the file is stored on the remote server and where you want to save it locally.

Using SSH Keys Instead of Passwords

Using SSH keys instead of passwords improves security and makes file transfers more efficient. Unlike passwords, SSH keys prevent brute-force attacks and allow for passwordless authentication. This method is ideal for automating file transfers, reducing the risk of compromised credentials. Before setting up SCP in PHP with SSH keys, you need to generate and configure them properly.

Step 1: Generate SSH Keys

First, generate an SSH key pair on your local machine. This will create a public and private key that will be used for authentication. Open a terminal and run the following command:

ssh-keygen -t rsa -b 4096

This creates two files:

  • Private key: Stored on your local machine (e.g., ~/.ssh/id_rsa).
  • Public key: Needs to be copied to the remote server.

Step 2: Add the Public Key to the Remote Server

Use the following command to copy your public key:

ssh-copy-id username@remote.server.com

Alternatively, manually add the key to ~/.ssh/authorized_keys on the remote server.

Step 3: Update Your PHP Code to Use SSH Keys

Now that your public key is stored on the remote server, update your PHP script to use SSH key authentication instead of a password. This ensures secure and automated file transfers without storing passwords in your code.

$connection = ssh2_connect('remote.server.com', 22);
ssh2_auth_pubkey_file($connection, 'username', '/path/to/id_rsa.pub', '/path/to/id_rsa');

Replace /path/to/id_rsa.pub and /path/to/id_rsa with the actual paths to your key files.

Copying Files from a Remote Server to Your Local Machine

If you need to download a file from a remote server, you can use the ssh2_scp_recv() function.

Step 1: Establish an SSH Connection

Connect to the remote server the same way as before:

$connection = ssh2_connect('remote.server.com', 22);  
ssh2_auth_password($connection, 'username', 'password');  

Step 2: Download the File

Once connected, use ssh2_scp_recv() to pull a file:

ssh2_scp_recv($connection, '/remote/path/file.txt', '/local/path/file.txt');  

Make sure the paths reflect the actual locations of the file on the remote server and where you want to save it on your local machine.

Using SSH Keys for Better Security

Instead of using a password, you can authenticate with SSH keys. This method is more secure and eliminates the need to store passwords in your code.

Step 1: Generate SSH Keys

On your local machine, open a terminal and run:

ssh-keygen -t rsa -b 4096

This will generate two files:

  • id_rsa (private key)
  • id_rsa.pub (public key)

Step 2: Copy the Public Key to the Remote Server

Now that you have generated an SSH key, you need to add the public key to the remote server. This step allows the server to authenticate your PHP script securely without requiring a password. Use the following command to copy your key automatically:

ssh-copy-id username@remote.server.com

If ssh-copy-id isn’t available, manually add the public key to the ~/.ssh/authorized_keys file on the remote server.

Step 3: Update Your PHP Code

Modify your script to use SSH keys instead of a password:

$connection = ssh2_connect('remote.server.com', 22);  
ssh2_auth_pubkey_file($connection, 'username', '/path/to/id_rsa.pub', '/path/to/id_rsa');  

Replace /path/to/id_rsa.pub and /path/to/id_rsa with the actual paths to your key files.

Security Best Practices

To ensure secure and reliable SCP file transfers in PHP, follow these best practices:

  • Use SSH keys instead of passwords – They prevent brute-force attacks.
  • Restrict SSH access – Allow only specific users and IPs to connect.
  • Limit file permissions – Use the lowest necessary permissions when transferring files.
  • Disable root login via SSH – Configure your server to prevent direct root access.
  • Enable logging – Track failed authentication attempts and unauthorized access.

Table: Comparison of Several File Transfer Methods

MethodSecuritySpeed & PerformanceSupports Multiple FilesBest ForDrawbacks
SCP (Secure Copy Protocol)High (Encrypted via SSH)Moderate (Can be slow for large files)No (Transfers one file at a time)Simple, secure file transfers over SSHCannot resume interrupted transfers
SFTP (SSH File Transfer Protocol)High (Encrypted via SSH)Faster than SCP (Better for large files)Yes (Supports directory listing and batch transfers)Managing multiple files, large file transfersSlightly more complex than SCP
rsync (Remote Synchronization)High (SSH encryption supported)Very fast (Transfers only changed parts of files)Yes (Efficient for bulk transfers)Syncing files between servers, backupsRequires rsync to be installed on both servers
FTP (File Transfer Protocol)Low (Plaintext unless using FTPS)High (Optimized for large transfers)YesPublic file downloads, legacy systemsLess secure, requires extra configuration for encryption
FTPS (FTP Secure)Medium (SSL/TLS encryption)HighYesSecure file transfers without SSHMore complex setup than SCP or SFTP

Key Takeaways:

  • SCP is great for one-time, secure file transfers but lacks support for batch transfers.
  • SFTP is a better alternative when transferring multiple files or large datasets.
  • rsync is the best option for synchronizing files between servers efficiently.
  • FTP and FTPS are used mainly for public file sharing or legacy applications, but they lack SSH-level security.

Troubleshooting Common SCP Errors

Even with the correct setup, SCP file transfers in PHP can sometimes fail due to authentication errors, incorrect file permissions, or SSH connection issues. Understanding these common problems can help you resolve transfer failures quickly and ensure smooth automation. Below are some of the most frequent SCP errors and their solutions.

1. SSH2 Extension Not Found

Error Message:
Call to undefined function ssh2_connect()

  • Make sure the SSH2 extension is installed (php -m | grep ssh2).
  • If missing, follow the installation steps mentioned earlier.
  • Restart the web server after enabling the extension.

2. Authentication Fails

Error Message:
Unable to authenticate with username and password

  • Double-check your username and password.
  • If using SSH keys, verify that the private key is correctly referenced.
  • Make sure the remote server allows SSH connections (sshd service should be running).

3. Permission Denied

Error Message:
scp: /remote/path/file.txt: Permission denied

  • Ensure the user has write permissions on the destination folder.
  • Run chmod 644 /remote/path/ on the remote server.
  • If needed, use chown username:group /remote/path/ to assign ownership.

4. SCP Transfer Freezes or Is Slow

  • Check server load with top or htop.
  • If transferring large files, consider compressing them before sending.
  • Use scp -C for compression if using the SCP command line.
  • Optimize network settings to avoid latency issues.

Performance Considerations for Large File Transfers

While SCP encrypts file transfers for security, it isn’t always the most efficient method for large files. Since SCP transfers entire files rather than syncing changes, it may result in longer transfer times and higher resource usage, especially over slow networks. If you’re transferring large datasets, media files, or backups, optimizing your SCP settings can significantly improve performance. Below are some best practices for speeding up SCP transfers in PHP.

  • Use batch transfers – Instead of sending many small files individually, compress them into a .tar.gz or .zip archive.
  • Increase SSH buffer size – Modify TCPWindowSize in SSH config (/etc/ssh/sshd_config).
  • Enable compression – SCP supports compression when using command-line scp -C, but PHP’s ssh2_scp_send() doesn’t have built-in compression. Instead, manually compress files before sending.

If performance is critical, consider using rsync or SFTP, which are more efficient for handling large files.

Alternative: Using SFTP Instead of SCP

SFTP (SSH File Transfer Protocol) is an alternative to SCP that provides more flexibility and reliability for managing remote files in PHP. Unlike SCP, which is a simple one-time file transfer tool, SFTP allows for advanced operations like resuming failed transfers, modifying file permissions, and retrieving directory listings.

If you frequently transfer large files or need more control over file handling, SFTP is the better option. Setting up SFTP in PHP requires establishing an SSH connection and using the SFTP protocol to read and write files.

To transfer files securely using SFTP in PHP, follow these steps. This method ensures reliable file uploads and downloads, especially when dealing with large datasets or unstable network conditions.

Step 1: Establish an SFTP Connection

// Establish an SSH connection to enable SFTP file transfer  
$connection = ssh2_connect('remote.server.com', 22);  
ssh2_auth_password($connection, 'username', 'password');  

// Initialize SFTP session  
$sftp = ssh2_sftp($connection);  

Step 2: Upload a File

// Open the file on the remote server in write mode  
$file = fopen("ssh2.sftp://$sftp/remote/path/file.txt", 'w');  

// Read the local file and write its contents to the remote file  
fwrite($file, file_get_contents('/local/path/file.txt'));  

// Close the file to save changes  
fclose($file);  

Step 3: Download a File

// Read the remote file contents  
$file = file_get_contents("ssh2.sftp://$sftp/remote/path/file.txt");  

// Save the file locally  
file_put_contents('/local/path/file.txt', $file);  

SFTP is more robust and flexible than SCP, making it a great alternative for handling large-scale file transfers in PHP.

Bonus: Automating File Transfers with SCP in PHP

In many scenarios, developers need to automate secure file transfers between servers, such as backing up files, deploying code, or syncing logs. Using SCP in PHP, you can schedule a script to run at specific intervals, ensuring seamless file transfers without manual intervention.

Below is a real-world PHP script that automates file transfers using SCP. It supports both file uploads and downloads, handles errors gracefully, and can be scheduled using a cron job or a task scheduler.

Automated SCP File Transfer Script in PHP

<?php
// Define server details
$remoteServer = 'remote.server.com';
$port = 22; // Default SSH port
$username = 'your-username';
$privateKey = '/path/to/id_rsa'; // Path to your private SSH key
$localFile = '/local/path/file.txt'; // File to upload
$remoteFile = '/remote/path/file.txt'; // Destination path on remote server

// Establish SSH connection
$connection = ssh2_connect($remoteServer, $port);

if (!$connection) {
    die("Error: Could not connect to remote server");
}

// Authenticate using SSH key (recommended for security)
if (!ssh2_auth_pubkey_file($connection, $username, "$privateKey.pub", $privateKey)) {
    die("Error: Authentication failed. Check SSH keys.");
}

// Function to upload a file using SCP
function uploadFile($connection, $localFile, $remoteFile)
{
    if (!ssh2_scp_send($connection, $localFile, $remoteFile, 0644)) {
        echo "Error: File upload failed\n";
    } else {
        echo "Success: File uploaded to $remoteFile\n";
    }
}

// Function to download a file using SCP
function downloadFile($connection, $remoteFile, $localFile)
{
    if (!ssh2_scp_recv($connection, $remoteFile, $localFile)) {
        echo "Error: File download failed\n";
    } else {
        echo "Success: File downloaded to $localFile\n";
    }
}

// Choose action: Upload or Download
$action = 'upload'; // Change to 'download' if needed

if ($action === 'upload') {
    uploadFile($connection, $localFile, $remoteFile);
} else {
    downloadFile($connection, $remoteFile, $localFile);
}

// Close the connection
unset($connection);
?>

How This Script Works

  1. Establishes an SSH connection to the remote server using the SSH2 extension.
  2. Authenticates using an SSH key instead of a password (more secure).
  3. Uploads or downloads a file based on the selected action (upload or download).
  4. Includes error handling to check for failed connections and authentication issues.
  5. Can be scheduled as a cron job for automated transfers.

Scheduling the Script with a Cron Job

To run this script automatically at regular intervals, add the following line to your cron job (Linux):

*/30 * * * * php /path/to/scp_script.php >> /var/log/scp_transfer.log 2>&1

This will execute the script every 30 minutes and log the output.

For Windows Task Scheduler, create a new task and set the action to:

php C:\path\to\scp_script.php

This script is useful for automated backups, file syncing, or secure deployments.

Final Thoughts

Using SCP in PHP is a secure way to transfer files between servers, but it has limitations for large file transfers. If you need better performance and error handling, SFTP is a more efficient alternative.

In this guide, we covered:

  • Installing the SSH2 extension for SCP
  • Transferring files with passwords and SSH keys
  • Troubleshooting errors like authentication failures and permissions issues
  • Optimizing performance for large file transfers
  • Using SFTP as an alternative to SCP

By following these steps, you can securely automate file transfers in PHP without manual intervention.

FAQs

What is SCP in PHP?

SCP (Secure Copy Protocol) in PHP allows secure file transfers between servers using SSH encryption.

Is SCP better than SFTP?

SCP is faster for simple file transfers, but SFTP is better for handling large files, directory listings, and resumable downloads.

How can I fix SCP “Permission Denied” errors?

Check the permissions and file ownership on the remote server. If needed, run chmod 644 or chown to give the correct user access.

Can I transfer multiple files at once with SCP?

No, SCP only transfers one file at a time. To transfer multiple files, use SFTP or compress files into an archive before sending them.

Is SCP secure?

Yes, SCP encrypts both the files and login credentials using SSH, making it safe for remote file transfers.

Photo of author
As Editor in Chief of HeatWare.net, Sood draws on over 20 years in Software Engineering to offer helpful tutorials and tips for MySQL, PostgreSQL, PHP, and everyday OS issues. Backed by hands-on work and real code examples, Sood breaks down Windows, macOS, and Linux so both beginners and power-users can learn valuable insights. For questions or feedback, he can be reached at sood@heatware.net.