Как преобразовать запрос на загрузку файла / файлов, сделанный с помощью Filepicker, в аналогичный запрос, выполненный с помощью простых элементов управления HTML-файлом в PHP?

В моей форме есть простой элемент управления HTML-файлом. Это динамический характер, означает, что пользователь может загрузить один или несколько файлов. Его HTML выглядит следующим образом:

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

Если я загружаю два изображения, используя вышеуказанный элемент управления HTML-файлом, и отправляю форму, я получаю следующее $_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
)

)

)

Теперь в соответствии с новым требованием я должен использовать Filepicker вместо простого элемента управления HTML File / s для загрузки файлов на сервер. Но проблема, с которой я сталкиваюсь, заключается в том, что дальнейшая логика кода и манипуляции уже были написаны с учетом вышеуказанного массива$_FILES) содержание.

Итак, я хочу преобразовать запрос, поступающий через Filepicker, в тот же формат, что и массив $_FILES чтобы не было необходимости вносить какие-либо изменения в логику и манипуляции с уже написанным кодом.

Позвольте мне объяснить вам сценарий более четко: если пользователь выбирает один или несколько файлов изображений из Google Диска через Filepicker и отправляет форму, запрос будет содержать URL-адреса тех изображений, которые генерируются Filepicker, и имена файлов.

Я хочу использовать эти данные и сформировать массив как вышеупомянутый массив ($_FILES).

10

Решение

Предполагая, что вы используете 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);
}

Я чувствую, что приведенный выше код довольно прост, но вот как getFilepickerFiles() работает (вы должны были прочитать Остальная API документация перед прочтением)

$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));

Попытка загрузить файл в $tmp используя copy() с URL-адресом в качестве источника.
Значение, возвращаемое copy() является TRUE на успех и FALSE на провал.
Значения ошибок присутствуют в $_FILES являются UPLOAD_ERR_OK в случае успеха и любой другой ценности в противном случае (источник, Я иду с UPLOAD_ERR_NO_FILE здесь в случае неудачи).
Таким образом, чтобы назначить значимое значение ошибки, мы используем троичный оператор для добавления UPLOAD_ERR_OK к списку кодов ошибок, если copy() возвращается TRUE, а также 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);

Получить метаданные файла, используя URL в качестве аргумента file_get_contents(), который должен возвращать массив JSON, который мы декодируем в ассоциативный массив, используя json_decode(/*...*/, TRUE),
Так как мы добавили &filename=true&mimetype=true до конца URL мы получим только значения filename а также mimetype — нам не нужно все остальное.
Декодированный массив, который мы назначаем $meta;

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

Добавьте значения filename а также mimetype от только что декодированного массива JSON до списков имен файлов и типов MIME соответственно.

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

Вернуть массив с image ключ, указывающий на массив файлов, которые мы создали.

И мы сделали.


Я не собираюсь создавать целый веб-сайт для размещения файлов, потому что для написания этого ответа потребуется в пять раз больше времени.
Поэтому я боюсь, что не смогу предоставить вам полностью работающее живое демо.

К сожалению, ни 3v4l ни codepad включите потоковую упаковку HTTPS, так что я даже не могу предоставить вам демонстрацию концепции «посмотрите сами».

Лучшее, что я могу сделать, — это, вероятно, скриншот окна моего терминала (нажмите, чтобы увеличить):

введите описание изображения здесь

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]