2015-04-30 26 views
10

Mam proste sterowanie plikami HTML w moim formularzu. Ma on charakter dynamiczny, co oznacza, że ​​użytkownik może przesłać jeden lub wiele plików. Jego HTML jest następujący:Jak przekonwertować żądanie przesyłania pliku/pliku wykonane za pomocą narzędzia Filepicker na podobne żądanie wykonane za pomocą prostej kontroli pliku HTML w PHP?

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

Gdybym przesłać dwa zdjęcia przy użyciu wyżej kontroli plików HTML i przesłać formularz dostaję następujący w $_FILES tablicy (wyjście z 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 
       ) 

     ) 

) 

Teraz według nowe wymaganie Muszę używać Filepikera zamiast prostych Kontrolek plików HTML do wysyłania plików na serwer. Ale problem, z którym się borykam, polega na tym, że dalsza logika kodu i manipulacja zostały już napisane, biorąc pod uwagę treść powyższej macierzy ($_FILES).

Tak więc, chcę przekonwertować żądanie przychodzące przez Filepicker na ten sam format, co w przypadku tablicy $_FILES, aby nie było potrzeby wprowadzania żadnych zmian w już napisanej logice kodu i manipulacjach.

Pozwólcie, że wyjaśnię wam dokładniej scenariusz, jeśli użytkownik wybierze jeden lub więcej plików graficznych z Dysku Google za pośrednictwem narzędzia Filepicker i prześle formularz, wniosek będzie zawierał adresy URL tych obrazów, które zostały wygenerowane przez Filepicker i nazwy plików.

Chcę użyć tych danych i utworzyć tablicę jak powyżej ($_FILES).

+0

Jeśli można podać filepicker kod integracji, która pomoże, gdyż istnieje inna metoda robi to jak [za pomocą widżetu] (https://www.filepicker.com/documentation/file_ingestion/widgets/pick), [Javascript pick multiple] (https://www.filepicker.com/documentation/file_ingestion/javascript_api/pick_multiple) , [wybór i przechowywanie kodu javascript] (https://www.filepicker.com/documentation/file_ingestion/javascript_api/pick_and_store), itp. i odpowiedź może być różna dla różnych sposobów integracji –

Odpowiedz

6

Zakładając, że PHP 5.2.1 lub wyższe i może wykorzystywać owijkę strumień HTTPS copy() i file_get_contents() funkcja ta powinna być wszystkie potrzebne:

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

Funkcja wykonuje szereg znaczników (np jako hFHUCB3iTxyMzseuWOgG) jako argument.
można nazwać jak

getFilepickerFiles(array('hFHUCB3iTxyMzseuWOgG')); 

Nie wiem dokładnie co Filepicker przechodzi do serwera, ale jeśli jest to pełny adres URL pliku jak

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

następnie można wyodrębnić tokeny jak to:

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

można również umieścić, że prawo do getFilepickerFiles() aby wziąć tablicę adresów URL plików zamiast:

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

Wyjaśnienie

czuję się jak w powyższym kodzie jest raczej proste, ale oto jak getFilepickerFiles() prace (powinieneś przeczytać Rest API documentation przed przeczytaniem tego):

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

Initialize $files do tablicy takiej jak $_FILES bez plików.

$tmpdir = sys_get_temp_dir(); 

Pobierz katalog, w którym przechowywane są pliki tymczasowe, ponieważ mamy zamiar pobrać pliki tam (Ta funkcja wymaga PHP 5.2.1 lub wyższej).

foreach($urls as $url) 

To, co powinno być foreach powinno być jasne.

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

budować naszą tymczasową ścieżkę, na wzór $_FILES (czyli ścieżkę do folderu plików tymczasowych, ciąg „php”, a niektóre losowych znaków).
Nazwę tę przypisujemy do $tmp (dla łatwego późniejszego użycia) i dodajemy ją do listy ścieżek plików.

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

Spróbuj pobrać plik do $tmp za pomocą copy() z adresem URL jako źródła.
Wartość zwrócona przez copy() to TRUE w przypadku sukcesu i FALSE w przypadku niepowodzenia.
Wartości błędów występujące w $_FILES to UPLOAD_ERR_OK w przypadku sukcesu i inne wartości w inny sposób (source, w przypadku niepowodzenia wystąpię z UPLOAD_ERR_NO_FILE).
Aby przypisać sensowną wartość błędu, używamy operatora trójargumentowego, aby dodać UPLOAD_ERR_OK do listy kodów błędów, jeśli copy() zwraca w innym przypadku TRUE i UPLOAD_ERR_NO_FILE.

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

Sprawdź rozmiar pliku i dodaj go do listy rozmiarów plików.

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

Get metadanych pliku przy użyciu adresu URL jako argument file_get_contents(), która powinna zwracać tablicę JSON że dekodowania do tablicy asocjacyjnej z wykorzystaniem json_decode(/*...*/, TRUE).
Ponieważ dodaliśmy &filename=true&mimetype=true na końcu adresu URL, otrzymamy tylko wartości filename i mimetype - nie potrzebujemy całej reszty.
Dekodowana tablica przypisana do $meta;

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

Dodaj wartości filename i mimetype z tylko dekodowane tablicy JSON do wykazów nazw plików i typów MIME odpowiednio.

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

zwraca tablicę z kluczem wskazując na tablicy plików stworzyliśmy image.

Skończyliśmy.


Demo? :(

Nie zamierzam budować dla tego całego serwisu hostingowego plików, ponieważ zajęłoby to pięciokrotność czasu potrzebnego na napisanie tej odpowiedzi:
Obawiam się, że nie mogę ci zapewnić z w pełni działającą demonstracją na żywo.

Niestety, ani 3v4l, ani codepad nie mają włączonego strumienia streamów HTTPS, więc nie jestem w stanie przedstawić "demonstracyjnej wersji demonstracyjnej" koncepcji "zobacz dla siebie".

Najlepsze, co mogę zrobić, to prawdopodobnie zrzut ekranu z mojego okna terminala (kliknij aby powiększyć):

enter image description here

+0

Po pierwsze anki za twoją pomoc. Naprawdę doceniam wysiłki, które wkładasz, aby rozwiązać mój problem i pomóż mi rozwiązać ten problem. Ale chcę mieć tę samą wydajność co $ _FILES. Podczas próby struktura tablic jest zupełnie inna. Na początku tablicy brakuje klucza ['image']. Czy możesz wprowadzić niezbędne zmiany w kodzie, aby dodać klucz ['image'] i uczynić wynikową tablicę podobną do $ _FILES. Jeszcze raz dziękuję. – PHPLover

+0

Masz rację, tęskniłem za tym. Zaktualizowałem moją odpowiedź. – Siguza

+0

Próbowałem twojego kodu. Byłem także w stanie przekonwertować tablicę na pożądany format. Ale znowu pojawił się nowy problem. Plik nie jest przesyłany do serwera po przetworzeniu tablicy $ files (tej, którą otrzymaliśmy z żądania fileplera). Czy spotkałeś się z tym samym problemem? – PHPLover