10

フォームに単純な HTML ファイル コントロールがあります。これは本質的に動的であり、ユーザーが 1 つまたは複数のファイルをアップロードできることを意味します。その HTML は次のとおりです。

<input type="file" id="image_book" class="image_book upload" name="image[]" accept="image/*" value=""/>

上記の HTML ファイル コントロールを使用して 2 つの画像をアップロードし、フォームを送信すると、$_FILES配列で次のようになります (の出力print_r($_FILES);):

Array
(
    [image] => Array
        (
            [name] => Array
                (
                    [0] => Aurbd-b3582991-large.jpg
                    [1] => BL_Miller_GD_Square_KV_300dpi_A2.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpSt8CJJ
                    [1] => /tmp/phpibFjR2
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 519179
                    [1] => 86901
                )

        )

)

新しい要件に従って、単純な HTML ファイル コントロールの代わりに Filepicker を使用してファイルをサーバーにアップロードする必要があります。$_FILESしかし、私が直面している問題は、上記の array's( ) の内容を考慮して、さらなるコード ロジックと操作が既に記述されていることです。

そこで、Filepicker からのリクエストを配列と同じ形式に変換して$_FILES、既に記述されているコード ロジックと操作を変更する必要がないようにしたいと考えています。

シナリオをより明確に説明しましょう。ユーザーが Filepicker を介して Google ドライブから 1 つ以上の画像ファイルを選択し、フォームを送信すると、要求には Filepicker によって生成された画像の URL とファイル名が含まれます。

このデータを使用して、上記の array( $_FILES) のように配列を形成したいと考えています。

4

1 に答える 1

6

PHP 5.2.1 以降を使用していて、 および で HTTPS ストリーム ラッパーを使用できると仮定するcopy()file_get_contents()、必要なのはこの関数だけです。

function getFilepickerFiles($tokens)
{
    $files = array('name' => array(),
                   'type' => array(),
                   'tmp_name' => array(),
                   'error' => array(),
                   'size' => array());
    $tmpdir = sys_get_temp_dir();
    foreach($tokens as $token)
    {
        $files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;
        $files['error'][] = copy('https://www.filepicker.io/api/file/'.$token, $tmp) ? UPLOAD_ERR_OK : UPLOAD_ERR_NO_FILE;
        $files['size'][] = filesize($tmp);
        $meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);
        $files['name'][] = $meta['filename'];
        $files['type'][] = $meta['mimetype'];
    }
    return array('image' => $files);
}

この関数は、トークンの配列 ( などhFHUCB3iTxyMzseuWOgG) を引数として取ります。
次のように呼び出すことができます

getFilepickerFiles(array('hFHUCB3iTxyMzseuWOgG'));

Filepicker がサーバーに何を渡すか正確にはわかりませんが、次のような完全なファイル URL の場合

https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG

次に、次のようにトークンを抽出できます。

$tokens = array();
foreach($urls as $url)
{
    $matches = array();
    preg_match('# ^https://www\\.filepicker\\.io/api/file/([^/]*)/?', $url, $matches);
    $tokens[] = $matches[1];
}
// Pass $tokens to getFilepickerFiles()

getFilepickerFiles()代わりにファイル URL の配列を取るために、その権利を入れることもできます:

function getFilepickerFiles($urls)
{
    $files = array('name' => array(),
                   'type' => array(),
                   'tmp_name' => array(),
                   'error' => array(),
                   'size' => array());
    $tmpdir = sys_get_temp_dir();
    foreach($urls as $url)
    {
        $matches = array();
        preg_match('# ^https://www\\.filepicker\\.io/api/file/([^/]*)/?', $url, $matches);
        $token = $matches[1];
        $files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;
        $files['error'][] = copy('https://www.filepicker.io/api/file/'.$token, $tmp) ? UPLOAD_ERR_OK : UPLOAD_ERR_NO_FILE;
        $files['size'][] = filesize($tmp);
        $meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);
        $files['name'][] = $meta['filename'];
        $files['type'][] = $meta['mimetype'];
    }
    return array('image' => $files);
}

説明

上記のコードはかなり単純だと思いますが、仕組みは次のとおりです (これを読む前に、 Rest API のドキュメントgetFilepickerFiles()を読んでおく必要があります)。

$files = array('name' => array(),
               'type' => array(),
               'tmp_name' => array(),
               'error' => array(),
               'size' => array());

$filesファイルを含まないような配列に初期化し$_FILESます。

$tmpdir = sys_get_temp_dir();

ファイルをそこにダウンロードするため、一時ファイルが保存されているディレクトリを取得します (この関数には PHP 5.2.1 以降が必要です)。

foreach($urls as $url)

明確にするforeach必要があります。

$files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;

パターンに従って、一時ファイル パスを$_FILES作成します (つまり、一時ファイル フォルダーのパス、文字列 "php"、およびいくつかのランダムな文字)。
その名前を$tmp(後で簡単に使用できるように) 割り当て、ファイル パスのリストに追加します。

$files['error'][] = (int)(!copy('https://www.filepicker.io/api/file/'.$token, $tmp));

URL をソースとして$tmp使用して、ファイルのダウンロードを試みます。 によって返される値は、成功時と失敗時です。 に存在するエラー値は、成功した場合とその他の値です ( source、失敗した場合はここで使用します)。 したがって、意味のあるエラー値を割り当てるために、三項演算子を使用してエラー コードのリストに if returnsを追加し、そうでない場合に追加します。copy()
copy()TRUEFALSE
$_FILESUPLOAD_ERR_OKUPLOAD_ERR_NO_FILE
UPLOAD_ERR_OKcopy()TRUEUPLOAD_ERR_NO_FILE

$files['size'][] = filesize($tmp);

ファイルのサイズを照会し、ファイル サイズのリストに追加します。

$meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);

への引数として URL を使用してファイル メタデータを取得しますfile_get_contents()。これは、 を使用して連想配列にデコードする JSON 配列を返す必要がありますjson_decode(/*...*/, TRUE)。URL の末尾に
追加したため、取得するのは値のみであり、残りはすべて必要ありません。 に割り当てるデコードされた配列。&filename=true&mimetype=truefilenamemimetype
$meta

$files['name'][] = $meta['filename'];
$files['type'][] = $meta['mimetype'];

filename値を追加し、mimetypeデコードしたばかりの JSON 配列からファイル名と MIME タイプのリストにそれぞれ追加します。

return array('image' => $files);

image作成したファイルの配列を指すキーを持つ配列を返します。

これで完了です。


デモ?:(

この回答を書くのに必要な時間の 5 倍の時間がかかるため、このためにファイル ホスティング Web サイト全体を構築するつもりはありません。
申し訳ありませんが、完全に機能するライブ デモを提供することはできません。

残念ながら、3v4lcodepadもHTTPS ストリーム ラッパーを有効にしていないため、「自分の目で確かめる」概念実証のデモを提供することさえできません。

私ができる最善の方法は、おそらくターミナル ウィンドウのスクリーンショットです (クリックして拡大)。

ここに画像の説明を入力

于 2015-05-02T19:56:37.287 に答える