几天前在@梓喵出没那里获悉WordPress有一套自己的HTTP命令API的时候,瞥到了一丝改进本地调试环境的曙光。心里就像种了草,这些天一番捣鼓,终于被我搞通了几个函数的前世今生。
虽然梓猫出没那里后面一篇也是说这套API的,但他的侧重点跟我这篇的侧重点毫无关联。
为啥我要研究WordPress怎么使用代理呢?这跟我的调试环境有关。本人一般在公司的xampp下调试WordPress插件和主题。这不是重点,重点是我们公司的网络访问是有白名单的,大多数网址都被公司的小墙拦下了。于是很多插件的网络功能没法调。如果能设代理当然就海阔凭鱼跃了不是?
第一个问题,WordPress如何设置代理?
很简单,我在十几年前就知道了。添加或修改wp-config.php文件。
define('WP_PROXY_HOST', '127.0.0.1'); //代理IP或host名 define('WP_PROXY_PORT', '25378'); //代理端口号 define('WP_PROXY_USERNAME', ''); //必要时加 define('WP_PROXY_PASSWORD', ''); //必要时加
几个字段一目了然,知道代理是什么的自然知道它们是什么,不解释。
第二个问题,WordPress如何使用默认代理?
答案是,使用wp_remote_request()系列API,WordPress会自动使用配置好的代理。
这组WordPress的API,包括wp_remote_request(),wp_remote_post(),wp_remote_get(),wp_remote_head ()等。详情见已被429的官网。
正常使用最多的就是wp_remote_post()和wp_remote_get()了。参数太多,需要改的却不多。举两个常用例子说明一下:
例1 调用API。
$url = "https://free-api.heweather.com/s6/weather/now?key=".HE_WEATHER_TOKEN."&location=CN101121501"; $args = array( 'sslverify' => false, 'headers' => array( 'Content-Type' => 'application/json;charset=UTF-8', 'Accept' => 'application/json', ),); $response = wp_remote_get($url,$args); if ( is_wp_error($response) ) { return; } else { $cache = json_decode(wp_remote_retrieve_body($response),true); }
上面这段代码是我所使用的“和天气”API获取实时天气的代码。其中,header里追加了json和编码,一般含中文内容的需要加编码的参,而json的参其实可加可不加。
有的API要求在header里加特殊参数以用来“对暗号”,照例追加便是。
返回值,WP自带了一个is_wp_error()函数,特好用,就不用自己费劲判断一堆数组套数组了。
返回的内容用wp_remote_retrieve_body()函数的好处同样是不用判断一堆套娃数组。
例2 将图片保存到服务器
preg_match('/avatar\/([a-z0-9]+)\?s=(\d+)/',$source,$tmp); $local = PLUGIN_DIR.'/wp-content/gallery/gravatar_cache/'.$tmp[1]; $default = home_url('/','https').'wp-content/gallery/gravatar_cache/default.png'; $dest = home_url('/','https').'wp-content/gallery/gravatar_cache/'.$tmp[1]; $url = 'http://www.gravatar.com/avatar/'.$tmp[1].'?s=64&d='.$default.'&r=G'; $response = wp_remote_get( htmlspecialchars_decode($url), array( 'timeout' => 300, 'stream' => true, 'filename' => $local ) ); if (is_wp_error($response)) { return '<img alt="" src="'.$default.'" class="avatar avatar-'.$tmp[2].'" width="'.$tmp[2].'" height="'.$tmp[2].'" />'; } return '<img alt="" src="'.$dest.'" class="avatar avatar-'.$tmp[2].'" width="'.$tmp[2].'" height="'.$tmp[2].'" />';
参数要注意两点,一个是stream=true,另一个filename是本地文件名。
第三个问题,要是不用WordPress函数,却想使用WordPress的Proxy,该怎么做?
简单。php一定有办法。改变函数的上下文即可。
还是一个取文件的例子:
$cxContext = stream_context_create(); $proxy = new WP_HTTP_Proxy(); if ($proxy->is_enabled()) { $proxy_str = $proxy->host().":".$proxy->port(); $stream_default_opts = array( 'http'=>array( 'proxy'=>$proxy_str, 'request_fulluri' => true, ), 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ), ); $cxContext = stream_context_create($stream_default_opts); } file_put_contents("./temp", file_get_contents($filename,false, $cxContext));
WP里提供了一个使用Proxy的类,名叫WP_HTTP_Proxy。很遗憾这个类没提供静态方法,所以只能声明实例后再调用。其实直接使用WP_PROXY_HOST和WP_PROXY_PORT也没有任何问题。
ssl那个参数跟目的地有关,不加有的服务器会报SSL错误。
如果Proxy需要用户名和密码的话,则要麻烦一点,用户名和密码要加到参数的header部分里。
$auth = base64_encode(WP_PROXY_USERNAME.":".WP_PROXY_PASSWORD); $stream_default_opts = array( 'http'=>array( 'proxy'=>WP_PROXY_HOST.":".WP_PROXY_PORT, 'request_fulluri' => true, ), 'header' => "Proxy-Authorization: Basic $auth", );
好了,这组对于大多数人没什么卵用的方法就介绍到这里。我想除了我这种本地调试环境有特殊上网需求的,恐怕没什么人会在服务器端再配个代理服务器吧。
说不定可以用来解决429问题?本人表示服务器在境外,从没遭遇过429,科科。
我觉得吧,这就是被公司生生逼出来的。我司只说上班时间不能炒股,其它规定都很自由,博客、贵圈之类爱写不写,唯一的缺点是实在没时间玩,忙得像狗……
我们不让上网不是为了效率,而是为了保密。客户要求的很严。
我去,除了突然大墙,还要突破公司的小墙,爬墙好累,哈哈哈
与人斗,其乐无穷。
直接一个代理出墙得了。= =、
“一个代理出墙”根本做不到。这是WP调试环境向外发的http request,不走浏览器。
改全局代理是找死,我敢改,内控半小时之后就会来找我谈话。
这里研究的就是让这种request走代理的方法。
最近wp不能升级得问题不也得靠这个解决。
理论上应该是可以,我没遇到这个问题所以没试过。