php向微信公众平台上传带有多张图片的图文消息时内容丢失该如何解决?

yangtoude
  • 326

1,问题:
将wordpress中的一篇文章作为永久素材上传到微信:
当文章中只有一张图片时,可以正常上传,且在微信公众平台查看此素材时,文字内容、图片都可以完整显示。
在文章中再添加一张图片(文章图片大于1张时),在微信后台查看此素材时发现文章不完整:从第一张图片开始以后的内容全部丢失。
补充说明:
(1)自己写了个插件,可以将wordpress文章上传到微信素材库。
主要过程:curl抓取文章中的图片并上传到微信素材库,获取url然后将wordpress文章中的图片src做相应替换。
然后构造图文消息json字符串上传到微信。
(2)wordpress文章中不添加任何样式,仅有<p>、<img>标签
2,代码:

// 上传图文消息代码
$raw = Curl::curl_post_wx( 'https://api.weixin.qq.com/cgi-bin/material/add_news?access_token='
    . $token, self::json_article( $post_ids, $token ), false );

/**
 * 将文章内容构造成json字符串
 *
 * @param array $post_ids
 * @param string $token
 * @return string json
 */
private function json_article( $post_ids, $token ) {
    $mp_article = '{"articles":[';
    foreach ( $post_ids as $post_id ) {
        $post = get_post( $post_id );
        $post_urls = self::preg_match_src( $post->post_content );
        if ( $post_urls ) {
            // 如果文章中有图片,将文章中的图片上传至微信素材库
            foreach ( $post_urls as $post_url ) {
                if ( strpos( $post_url, 'qpic.cn' ) === false ) {
                    // 如果图片没有上传到微信服务器
                    $res = Curl::curl_post_wx( 'https://api.weixin.qq.com/cgi-bin/material/add_material?'
                        . 'access_token=' . $token . '&type=image', false, Curl::curl_get_img( $post_url ) );
                    //替换文章内容img中的src地址
                    $post->post_content = str_replace( $post_url, $res['url'], $post->post_content );
                }
                $post->post_content = str_replace( '"', '\"', $post->post_content );
            }
        }

        // 获取缩略图并上传
        // 相应的code省略

        // 构造json
        $mp_article .= '{
            "title": "' . $post->post_title . '",
            "content_source_url": "' . get_permalink( $post_id, false ) . '",
            "thumb_media_id": "' . $thumb_res['media_id'] . '",
            "content": "' . htmlspecialchars_decode( $post->post_content ) . '",
            "show_cover_pic": 0,
        ';
        if ( !empty($post->post_excerpt ) ) {
            $mp_article .= '"digest": "' . $post->post_excerpt . '",';
        }
        $mp_article .= '},';
    }

    return rtrim($mp_article, ',') . ']}';
}

3,报错信息:微信未返回错误信息。
4,截图:无。
5,其他参考:
在CSDN上看到过tilun_099遇到过类似的问题:http://bbs.csdn.net/topics/39...
tilun_099的问题是:“在上传多图文素材时如果content的内容是纯文本是,可以上传成功,得到media_id,然后通过群发接口,手机可以正确获得多图文信息。可是如果content里面的内容含有html的标签,如<table>,<p>,等等时,上传后虽然也能获得media_id,群发后,手机得到的是单图文,而且这个单图文 有图片,标题,链接,就是没有具体内容。也就是content是空的。”
tilun_099最后解决他的问题的方法:“ 虽然没人回答,但我还是终于解决了。content里面的内空如果含有html标签的话,需要对内容进行一下转义。如果里面含有style=".."类似于这样的带""号的内容的话,就更需要注意了。

foreach ($news as &$item){
    foreach ($item as $k=>$v){
        if($k =='content'){
            $item[$k] = urlencode(htmlspecialchars(str_replace("\"","'",$v)));
            }else{
                $item[$k] = urlencode($v);
            }
        }
    }

就是要对html里面的“”引号先转成单引号,然后再将其转成html实体,这样在进行urlencode的时候就不会影响到标签了。

$data=array("articles"=>$news);
    $data=json_encode($data);
    $end_data= urldecode($data);
    $end_data= htmlspecialchars_decode($end_data);

上传之前再对内容进行urldecode和将html实体转成html标签,这样就OK了。
测试过的!”

我和他遇到的问题有点儿相似,但是不完全相同,我是直接构造的json。

回复
阅读 3.9k
1 个回答

是我代码的问题,写代码的时候不细心导致的,自己给自己挖了个坑。

if ( $post_urls ) {
            // 如果文章中有图片,将文章中的图片上传至微信素材库
            foreach ( $post_urls as $post_url ) {
                if ( strpos( $post_url, 'qpic.cn' ) === false ) {
                    // 如果图片没有上传到微信服务器
                    $res = Curl::curl_post_wx( 'https://api.weixin.qq.com/cgi-bin/material/add_material?'
                        . 'access_token=' . $token . '&type=image', false, Curl::curl_get_img( $post_url ) );
                    //替换文章内容img中的src地址
                    $post->post_content = str_replace( $post_url, $res['url'], $post->post_content );
                }
            }
        }
        // 下面这个替换应该放在foreach外,否则有多张图片时会进行多次替换
        // 最后还是放到判断文章中有无图片这个if语句外面,另外再加一条替换语句。
        // 否则如果有其他html标签(带有"或')时,还是会出现解析错误的问题
        $post->post_content = str_replace( '"', '\"', $post->post_content );
        $post->post_content = str_replace( ''', '\'', $post->post_content );        
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏