web-dev-qa-db-ja.com

サーバーBへのリモートアップロードファイル

私はこれが今までで最も難しいコーディングの一部であるかもしれないことを知っています、しかしそれを試してみることを考えました。

私は基本的にWordpressのメディアアップロードを通じてアップロードされたすべての(mp3)ファイルタイプを検出してそれらをオフサイトに送信しようとしているので、それらを(ftp接続)を通して別のサーバーにアップロードさせます。

以下は私が何時間もの研究の後に始めたコードで、私は立ち往生していると思います、正直言って私は良い時点でいるかどうかさえわかりません。私はWordpress/PHPについてもっと多くの知識を持っている人が私がやろうとしていることをアーカイブするのを手伝ってくれることを願っています。これは、メインサーバーが大きなファイルサイズで過負荷になるのを防ぎ、画像に限定するためです。

サーバーBにアップロードされる構造は、次のようになります。serverB.com/music/Year/month/file.mp3

年と月はワードプレスの投稿日( 'Y/m')から継承する必要があります。

それがアップロードされた後、wordpressに現れるリンクはファイルへのserverB.com URLのそれであるべきです。

ありがとうございました。以下は私が始めたコードです:

<?php
/* 
 * Change upload directory/server for mp3 files 
 * Only works in WordPress 3.3+
 */

add_filter('wp_handle_upload_prefilter', 'music_pre_upload');
add_filter('wp_handle_upload', 'music_post_upload');

function music_pre_upload($file){
add_filter('upload_dir', 'music_remote_upload_dir');
return $file;
}

function music_post_upload($fileinfo){
remove_filter('upload_dir', 'music_remote_upload_dir');
return $fileinfo;
}

function music_remote_upload_dir($path){    
$extension = substr(strrchr($_POST['name'],'.'),1);
if(!empty($path['error']) ||  $extension != 'mp3') { return $path; } // if other     filetype send to default uploads folder.

    /**
     * Change this to match your server
     * You only need to change the those with (*)
     * If marked with (-) its optional 
     */

    $post_date = '/' . date( 'Y/m' );

    $settings = array(
            'Host'          =>        'Host or IP',       // * the ftp-server hostname
            'user'          =>        'ftp-username',                // * ftp-user
            'pass'          =>        'ftp-pass',       // * ftp-password
            'cdn'           =>        'external-server.com',          // * This have to be a pointed domain or subdomain to the root of the uploads
            'path'          =>        '/music',                    // - ftp-path, default is root (/). Change here and add the dir on the ftp-server
            'date'          =>        $post_date          // Local post date
    );

    /**
     * Host-connection
     * Read about it here: http://php.net/manual/en/function.ftp-connect.php
     */

    if(function_exists('ftp_ssl_connect'))
     {

    $connection = ftp_ssl_connect( $settings['Host'] );

     }
        else
     {
    $connection = ftp_connect( $settings['Host'] );
     }

    /**
     * Login to ftp
     * Read about it here: http://php.net/manual/en/function.ftp-login.php
     */

    $login = ftp_login( $connection, $settings['user'], $settings['pass'] );

    /**
     * Check ftp-connection
     */

    if ( !$connection || !$login ) {
        die('Connection attempt failed, Check your settings');
    }

   ftp_pasv($resource, true); // To avoid rectify warning

   if( ftp_put( $connection, $settings['path'] . "/" . $settings['date'] . "/" . $file, FTP_BINARY ) ) {

      echo "successfully uploaded $file\n";

        } else {

      echo "There was a problem while uploading $file\n";
      }

      // close the connection
       ftp_close($conn_id); 



} // End function
6
Gmedy Cole

これは悪い考えです。あなたはあなたのサイトの完全性をいくつかの断片に分割しようとしていて、それぞれが異なるサーバー上にあり、追加の失敗ポイントを導入するでしょう。

あなたはそれを言います:

これは、メインサーバーが大きなファイルサイズで過負荷になるのを防ぎ、画像に制限するためです。

しかし、それは真実ではありません。静的ファイルを提供することはWebサーバがする最も簡単なタスクの1つであり、それらのサイズに関連している「過負荷」はありません。他のサーバーの帯域幅に対しても同様に支払うと仮定すると、それを実行することにはゼロポイントしかありません。

そのようなことをする唯一の理由はあなたがCDNにファイルをアップロードする必要がある時(まだ "pull"をサポートしていないもの)です、しかしあなたはそれの代わりにではなく通常のファイルアップロードプロセスに加えてすべきです。

1
Mark Kaplun

die('message');を追加して、失敗した場所をデバッグするためにそれを使用してください。 ftp://external-server.comだけでなく、external-server.comも試してみてください。また、あなたのFTPパスワードを使うようにしてください。パッシブモードではなくアクティブモードで試してください。私がFTPでアップロードしようとしていたとき、それは私がしなければならなかったことです。

また、FTPのパスワードが正しく暗号化されていることを確認してください。それをしていたとき、私のパスワードがシンボル%を使っていた問題を抱えていましたが、それを私のPHPで提出しようとすると、それを16進数として提出しなければなりませんでした。

また時々それはただ行方不明のセミコロン、それは最悪です。

1
Daniel