如何将 BLOB 与 JSON 和 PHP 一起使用?

Posted

技术标签:

【中文标题】如何将 BLOB 与 JSON 和 PHP 一起使用?【英文标题】:How to use BLOB with JSON and PHP? 【发布时间】:2011-06-18 19:59:48 【问题描述】:

我有一个带有 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;

【问题讨论】:

将图像本身存储在数据库中(而不仅仅是存储对远程文件系统中文件的引用)可能是一个糟糕的举动。有一个非常好的现有问题可以详细检查这个主题:Storing Images in DB - Yea or Nay? 我无法在远程文件系统中存储对文件的引用,因为应用程序的用户无法将照片上传到远程系统.....我在我的问题中告诉了它¿为什么有人给我投了反对票?? 为什么用户不能上传照片到系统? +1 这仍然是一个合理的问题,您是否同意他将照片存储在数据库中并不相关。 您的设置似乎非常低效,这可能是它如此缓慢的原因。为什么不能保存到文件系统,然后将文件名保存到数据库中?您可以为此和 PHP $_FILES 变量使用标准 HTTP 上传。这里有很多有用的链接:***.com/questions/2544517/… 【参考方案1】:

将请求分成两部分:

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

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

这意味着您发出两个 HTTP 请求而不是一个,但取决于应用程序,您可能能够异步加载图像,如果这样,从用户的角度来看,您通常会在感知应用程序响应时间方面获得很大收益。

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

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

如果您不能延迟加载图像,请考虑同时对图像和 JSON 执行并行请求。由于图像的二进制版本占用的网络带宽要少得多,并且一旦将数据传输到手机上的处理也少了很多,它看起来仍然会更快。

【讨论】:

【参考方案2】:

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

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

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

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

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

【讨论】:

【参考方案3】:

为什么不将您的图像作为文件转储到服务器上并在您的 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 或长文本字段作为文件写入您的服务器上,然后您可以从您的移动应用程序下载该文件。然后,您可以在一段时间后删除此临时文件。

希望对你有用

【讨论】:

【参考方案4】:

缓慢是来自 json/base64 编码 100K 的数据,还是来自数据库命中?它可能来自编码,并且将文件放入文件系统中(正如 cmets 中的每个人都在哭泣),在小范围内,不会有什么不同。

对操作的不同部分进行一些测量,并尝试找出其缓慢的原因。我不知道在没有 base64 的情况下如何将图像 blob 转换为 json 编码的字符串,我想您可以尝试转义所有内容,这可能同样慢,并希望解析器不会卡住它。

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

【讨论】:

速度慢来自 json/base64 编码 100K 的数据,你有我的问题上慢的确切代码,我编辑了它 那么慢是在客户端吗? mysql 和 php 的所有问题都可能被排除在外,人们可能会回答更多,而不是专注于错误的事情。帮不了你。

以上是关于如何将 BLOB 与 JSON 和 PHP 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 SQL Server 2012 与 php 一起工作?

将 Gmail API 与 PHP 一起使用:如何使 CLI 应用程序在浏览器中运行?

我如何使Figma API与Google App脚本API一起使用?

一起发送 JSON 和 blob

uniapp Blob路径转文件流 并且将json对象和文件流一起传入后台

如何使 windows 符号链接与 mod_php 一起工作?