上个星期痴迷于摆弄Typecho的插件,遇到了PHP发送POST请求失败的问题,在此记录一下。

起因

在【祭夜の咖啡馆】发现【typecho的微博头条同步插件】,简单地看了源码,打算上手自己写一个。

我需要申请微博的头条文章写入权限,然后利用微博提供的接口发布头条文章。

以下为头条文章发布接口相关信息。

请求URL: https://api.weibo.com/proxy/article/publish.json

请求参数:

参数名称类型是否必需描述
titlestring文章标题,限定32个中英文字符以内
contentstring正文内容,限制90000个中英文字符内,需要urlencode
coverstring文章封面图片地址url
summarystring文章导语
textstring与其绑定短微博内容,限制1900个中英文字符内
access_tokenstring认证token

问题

我自己编写相关代码,发现微博的服务器不能收到我发送的数据。即使我从Github上下载微博提供的demo,并修改access_token,也不能成功。浏览器展现的是一篇空白。

<?php
   // 发送POST请求相关参数
        $url = "https://api.weibo.com/proxy/article/publish.json";

        $data = array(
            'title' => "test_title",
            'content' => "test_content",
            'cover' => "https://api.xygeng.cn/bing/1920.php",
            'summart' => "test_summary",
            'text' => "test_summary",
            'access_token' => "****************",
        );

        // 发送POST请求
        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_URL, $url );
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );           
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data);
        $ret = curl_exec ( $ch );
        curl_close ( $ch );
        print_r($ret);

但是,如果我用Python发送相关请求,是没有问题的。

import json

import requests


class PostArticle:
    def __init__(self, data):
        self.data = data

    def action(self):
        req_url = "https://api.weibo.com/proxy/article/publish.json"
        r = requests.post(req_url, data=self.data)
        result = json.loads(r.text)
        # print(result)
        return result


data = {
    "title": "test_title",
    "content": "test_content",
    "cover": "https://api.xygeng.cn/bing/1920.php",
    "summary": "test_summary",
    "text": "test_text",
    "access_token": "****************"
}

t = PostArticle(data)
Result = t.action()
if Result['code'] == 100000:
    print("文章地址为:" + Result['data']['url'])
else:
    print("状态码:" + Result['code'])

解决

向大佬请教之后,问题解决了。

需要在PHP的代码中加入

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

关闭SSL验证。

一些想法

  • 微博提供的demo是几年前的,可能在旧版的PHP上可以正常使用,但是在新版的PHP上行不通。
  • 在百度上找了很多的答案,也在CSDN上逛了很久,都找不到解决问题的方法。最后思否上的大佬解决了我的问题。可能这都算不上什么问题,只是因为我不够了解这门语言。提出问题很重要。
  • 我还有进步的空间...