如何使用BLOB与JSON和PHP?

时间:2011-01-31 19:59:11

标签: php android json blob base64

我有一个带MySQL的远程数据库,我将我的应用程序用户的照片存储在数据库中,作为LONGTEXT类型的数据库的一行。

我使用Base64将照片转换为字符串。

我使用JSON和PHP连接到我的远程数据库,因为这个,我必须使用Base64,因为据我所知,JSON和PHP需要在参数上发送字符串,而使用Base64我可以将照片转换为字符串

它运作正常,但速度很慢。当我加载100 KB的照片时,需要花费很多时间,但是当我加载5 KB的照片时,只需要两到三秒钟。

一位朋友告诉我使用BLOB而不是Base64,但是如何使用BLOB和JSON以及PHP连接到数据库?此外,我需要将图像存储在表USER的一行上。这是因为用户没有权限将文件上传到远程服务器,但他们可以通过将照片作为字符串添加到表USER的一行中来上传照片。

感谢

编辑:

这是需要等待一段时间的代码(它在行中等待:while ((line = reader.readLine()) != null) {,等待reader.readLine()

此代码从远程数据库获取一个用户,需要花费一些时间在我的应用上显示用户

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

4 个答案:

答案 0 :(得分:8)

将请求分为两部分:

  • 首先使用除图像之外的所有内容下载JSON,然后将图像引用作为URL返回
  • 第二次将图像下载为二进制块,可能是异步,具体取决于应用程序

我假设您有http://example.com/userinfo/xxx之类的东西作为返回JSON的端点?添加类似http://example.com/userinfo_image/xxx的端点以仅返回图像,然后您可以将其作为二进制块返回,而不是在JSON中对其进行Base64编码。

这意味着您发出两个HTTP请求而不是一个,但是根据应用程序的不同,您可以异步执行图像加载,如果是这样,您通常可以从用户角度获得应用程序响应时间的大幅提升。 / p>

有关延迟加载图片的信息,请参阅Android开发者博客上的帖子以获取示例:

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

如果您无法延迟加载图像,请考虑同时对图像和JSON执行并行请求。使用图像的二进制版本可以减少网络带宽,并且一旦将数据传输到手机上,处理的处理就会少得多,它应该看起来速度更快。

答案 1 :(得分:1)

回答你的问题: 不,JSON不支持二进制数据,您必须在发送之前以某种方式对其进行转义。将其作为BLOB存储在MySQL中并不能解决您遇到的主要基础架构问题。

根据我的理解,你有一个将图片上传到PHP服务器的Android设备,这个PHP服务器将图片编码为Base64,将其放入JSON字符串然后将其发布到远程(远程是远程的) ?相同的数据中心?遍布全国?在外太空绕月球运行?)MySQL服务器通过某种HTTP接口,即MySQL服务器将Base64图像存储为LONGTEXT。为了获取图像,Android客户端向PHP发送请求,PHP向远程MySQL服务器发送请求,然后PHP必须对Base64进行解码并将其发送下来。

这非常低效,你将在每一步都遭受延迟。

编辑:好吧,这看起来像是客户端问题,而不是服务器端问题......

如果是这种情况,那么我建议查看帖子@ Uploading images to a PHP server from Android,因为他们应该有一些更有效的例子。

答案 2 :(得分:1)

为什么不将图像作为文件转储到服务器上并在json中返回写入文件的url?这就是你应该做你想做的事情,因为http是你应该用来通过网络传输图像的协议。

与此类似的代码应该在服务器上执行您想要的操作

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

这会将您的blob或longtext字段写为服务器上的文件,然后您可以从移动应用程序下载该文件。然后,您可以在一段时间后删除此临时文件。

希望这很有用

答案 3 :(得分:0)

缓慢来自json / base64编码100K数据,还是来自数据库命中?它可能来自编码,并且将文件放在文件系统中(正如评论中的每个人都在哭),小规模,不会产生一些差别。

对操作的不同部分进行一些测量,并尝试查明其缓慢的原因。我不知道你怎么把你的图像blob变成没有base64的json编码字符串,我想你可以尝试逃避一切,这可能同样慢,并希望解析器不会扼杀它。

您是在php中使用json_encode函数,还是手动构建字符串?尝试手动构建它。你是对数据库中的原始数据进行base64编码,还是在存储之前对其进行编码,你应该在存储之前对其进行编码,以便在输出时节省时间。