大文本字符串取出丢失内容

今天发现一个非常奇怪的问题,我保存一个很大的文本进数据库,然后取出来的时候发现少了不少内容。测试之后发现是Laravel的问题,用PDO查询是不会丢失的。

数据表结构如下:

    CREATE TABLE `articles` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `content` longtext NOT NULL COMMENT '内容',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4

测试代码如下:

    $article = new \App\Models\Article();
    $article->title = 'test';
    $article->content = str_repeat('a', 2000000);
    $article->save();

    $id = $article->id;

    $data1 = \App\Models\Article::find($id);
    var_dump(strlen($data1->content));

    $dbh = new PDO('mysql:host=localhost;dbname='.env('DB_DATABASE'), env('DB_USERNAME'), env('DB_PASSWORD'));
    $sth = $dbh->prepare('select * from articles where id = :id limit 1');
    $sth->bindValue(':id', $id);
    $sth->execute();
    $data2 = $sth->fetch(PDO::FETCH_OBJ);
    var_dump(strlen($data2->content));

结果如下:

int 1048576
int 2000000

PS:小于1048576的字符串是正常的,大于这个数字的都只返回1048576的长度

请问有知道这是什么问题的吗??这个神奇的数字是什么?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10
leo

这个神奇的数字是1024*1024

7年前 评论
leo

写了个demo,没有复现你的问题

7年前 评论

@leo 不好意思,没有看到回复。

我在laravel 5.1和5.3新创建的框架都试过有这个问题,但没有找到具体出现的原因。
开发环境:
OS X,PHP 7.0.14,MySQL5.7.17

是否有相关的参数没配置好?

但既然PDO能查到应该不是PHP的问题,奇怪的很啊。

目前用最笨的方法暂时“处理”了这个问题:

public function getContentAttribute($value)
  {
      //@todo 这是一个bug?保存大文本字符串,Laravel只会返回1048576个字符,暂时先用PDO查询,待解决

      if ($this->exists) {
          $dbh = new \PDO('mysql:host=localhost;dbname='.env('DB_DATABASE'), env('DB_USERNAME'), env('DB_PASSWORD'));
          $sth = $dbh->prepare('SELECT content FROM '. $this->getTable() .' WHERE id = :id');
          $sth->bindValue(':id', $this->id);
          $sth->execute();
          $data = $sth->fetch(\PDO::FETCH_OBJ);
          return $data->content;
      } else {
          return null;
      }
  }

  ...
}

哎呀我的天啊,每次看到这段代码都一阵阵心痛

7年前 评论

你看下my.cnf中的max_allowed_packet值是不是1M

7年前 评论

@Vanry 我的配置是max_allowed_packet = 16M

我觉得如果PDO能正常获取,那应该不管PHP和MySQL的问题

7年前 评论

坐等答案

7年前 评论

@Vergil 没有,不过觉得这个很好玩

7年前 评论
lijinma

Mark 一下

7年前 评论

@生活无限好 你有兴趣可以试试运行上面的代码看看有没这个问题,前面的人回复说没有,但我这边开发机和服务器确实也遇到

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!