2011-01-31 17 views
8

Ho un database remoto con MySQL e sto memorizzando le foto degli utenti della mia app sul database come una riga del database con il tipo LONGTEXT.Come utilizzare BLOB con JSON e PHP?

Trasformo le foto in una stringa con Base64.

Mi collego al mio database remoto con JSON e PHP, perché questo, devo usare Base64, perché come so, JSON e PHP devono inviare stringhe sui parametri, e con Base64 posso trasformare la foto in un stringa.

Funziona bene, ma è molto lento. Quando sto caricando una foto di 100 KB, ci vuole un sacco di tempo, ma quando sto caricando una foto di 5 KB ci vogliono solo due o tre secondi.

Un amico mi ha detto di utilizzare BLOB invece di Base64, ma come utilizzare BLOB con JSON e una connessione PHP al database? Inoltre, ho bisogno di memorizzare le immagini su una riga del tavolo USER. Questo perché gli utenti non hanno i privilegi per caricare i file nel server remoto, ma possono caricare le foto caricandole come una stringa in una riga della tabella USER.

grazie

EDIT:

questo è il codice dove ci vuole un tempo looot attesa (attende nella linea: while ((line = reader.readLine()) != null) {, che è in attesa reader.readLine())

questo codice ottiene un utente dal database remoto, ci vuole un loooooot di tempo per mostrare all'utente il mio app

public Friend RetrieveOneUser(String email) 
{ 

    Friend friend=null; 

    String result = ""; 
    //the parameter data to send 
    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
    nameValuePairs.add(new BasicNameValuePair("email",email)); 

    //http post 
    InputStream is=null; 
    try{ 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost(this.BaseURL + this.GetOneUser_URL); 
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
      HttpResponse response = httpclient.execute(httppost); 
      HttpEntity entity = response.getEntity(); 
      is = entity.getContent(); 
    }catch(Exception e){ 
      Log.e("log_tag", "Error in http connection "+e.toString()); 
    } 
    //convert response to string 
    try{ 

      BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
        sb.append(line + "\n"); 
      } 
      is.close(); 

      result=sb.toString(); 
    }catch(Exception e){ 
      Log.e("log_tag", "Error converting result "+e.toString()); 
    } 

    //parse json data 
    try{ 
      JSONArray jArray = new JSONArray(result); 


      for(int i=0;i<jArray.length();i++) 
      { 
        JSONObject json_data = jArray.getJSONObject(i); 
        friend=new Friend(json_data.getString("email"),json_data.getString("password"), json_data.getString("fullName"), json_data.getString("mobilePhone"), json_data.getString("mobileOperatingSystem"),"",json_data.getString("photo")); 
      } 
    } 
    catch(JSONException e){ 
      Log.e("log_tag", "Error parsing data "+e.toString()); 
    } 

    return friend; 
} 
+3

La memorizzazione delle immagini stesse nel database (piuttosto che la semplice memorizzazione di un riferimento a un file nel filesystem remoto) è probabilmente una cattiva mossa. C'è una domanda molto buona che esamina questo argomento in dettaglio: [Memorizzazione di immagini in DB - Sì o Nay?] (Http://stackoverflow.com/questions/3748/storing-images-in-db-yea-or- no) –

+0

non riesco a memorizzare un riferimento a un file nel filesystem remoto perché gli UTENTI della APP non possono caricare foto nel sistema remoto ..... l'ho detto nella mia domanda ¿perché qualcuno mi ha messo un voto negativo ?? – NullPointerException

+0

perché gli utenti non possono caricare foto nel sistema? – binnyb

risposta

8

segmento della domanda in due parti:

  • Prime download la JSON con tutto tranne l'immagine, restituisce un riferimento all'immagine come un URL invece
  • Seconda scaricare l'immagine come una porzione binaria, potenzialmente asincrona a seconda dell'app

Suppongo che tu abbia qualcosa come http://example.com/userinfo/xxx come endpoint che restituisce JSON? Aggiungere un endpoint come http://example.com/userinfo_image/xxx per restituire solo l'immagine, quindi è possibile restituirlo come un pezzo binario anziché Base64 che lo codifica nel JSON.

Significa che si effettuano due richieste HTTP invece di una, ma a seconda dell'applicazione si potrebbe essere in grado di caricare l'immagine in modo asincrono, e in tal caso normalmente si ottiene un grande guadagno nel tempo di risposta delle applicazioni percepito dal punto di vista dell'utente.

Per info sulle immagini lazy loading in background vedere il post sul blog Android Developers per un campione:

http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

Se non è possibile caricare pigro l'immagine in considerazione facendo richieste parallele sia per il immagine e il JSON allo stesso tempo. Con la versione binaria dell'immagine che richiede molta meno larghezza di banda di rete e molta meno elaborazione una volta che i dati sono stati ricevuti sul telefono, dovrebbe sembrare ancora molto più veloce.

0

Is la lentezza venuta da JSO n/base64 codifica 100K di dati, o dal colpo del database? Probabilmente è dalla codifica, e mettendo i file nel file system (come tutti i commenti stanno piangendo), su piccola scala, non farà alcuna differenza.

Effettuare alcune misurazioni sulle diverse parti dell'operazione e cercare di individuare il motivo per cui è lento. Non so in quale altro modo si otterrebbe un blob di immagine in una stringa codificata json senza base64, suppongo che si possa provare a sfuggire a tutto, il che potrebbe essere altrettanto lento, e sperare che il parser non si strozzi.

Si sta utilizzando la funzione json_encode in php o la costruzione manuale della stringa? Prova a costruirlo manualmente. Sei basato sulla codifica base64 dei dati grezzi dal database, o è codificato prima di essere memorizzato, dovresti codificarlo prima di essere archiviato per risparmiare tempo durante l'output.

+0

la lentezza sta venendo dalla codifica json/base64 100K di dati, hai il codice esatto che è lento sulla mia domanda, l'ho modificato – NullPointerException

+0

Quindi la lentezza è sul lato client? Probabilmente tutta la questione di mysql e php è stata lasciata fuori dalla domanda, e la gente avrebbe potuto rispondere di più invece di concentrarsi sulla cosa sbagliata. Non posso aiutarti lì. – profitphp

1

Per rispondere alla tua domanda: No, JSON non supporta i dati binari, devi prima evitarlo prima di inviarlo. Memorizzarlo come BLOB in MySQL non risolverà i principali problemi di infrastruttura che hai.

Da quello che ho capito, hai un dispositivo Android che sta caricando un'immagine su un server PHP, questo server PHP sta codificando l'immagine su Base64, inserendola in una stringa JSON e quindi pubblicandola su un remoto (come è remoto remoto? stesso centro dati? in tutto il paese? in tutto il mondo? nello spazio esterno in orbita attorno alla luna?) server MySQL attraverso un'interfaccia HTTP di qualche tipo, che il server MySQL sta memorizzando l'immagine Base64 come LONGTEXT. Per recuperare l'immagine, il client Android invia una richiesta a PHP, PHP invia una richiesta al server MySQL remoto, PHP quindi deve Base64 decodificare l'immagine e inviarla.

Questo è orribilmente inefficiente, subirete ogni latenza in ogni fase del processo.

Edit: ok sembra che questo è un problema lato client e non un problema lato server ...

Se questo è il caso, allora io suggerirei di controllare i messaggi @Uploading images to a PHP server from Android come dovrebbero avere un po ' esempi più efficienti.

1

Perché non scaricare l'immagine come file sul server e restituire l'URL del file scritto nel tuo json? Questo è davvero il modo in cui dovresti fare ciò che vuoi fare poiché http è il protocollo che dovresti usare per trasferire le immagini sul web.

codice simile a questo dovrebbe fare quello che vuoi sul server

//code to get your row from database 

    //Code that writes it to a file. 
    $Data = $row['myblobfield']; 

    $fp = fopen('myimgname.jpg', 'w'); 
    fwrite($fp, $Data); 

    fclose($fp);  

Questo scriverà il vostro blob o campi LongText come un file sul server che è quindi possibile scaricare dalla tua app mobile. È quindi possibile eliminare questi file temporanei dopo un intervallo.

Spero che questo è utile