我一直在尝试制作一个自定义的twitter小部件,它显示来自多个提要的最后几条推文。每个提要创建以下类的一个实例:
<?php
class Foo{
protected $name = '';
//opts
protected $numTweets = 3;
protected $transName = ''; // Name of value in database.
protected $backupName = '';
protected $cacheTime = 5; // Time in minutes between updates.
protected $exclude_replies = true; // Leave out @replies?
public function __construct( $username ){
$this->name = $username;
$this->transName = 'jctft3' . $username;
$this->backupName = 'jctfb3' . $username;
}
public function get_feed(){
$feed = get_transient( $this->transName );
// Do we already have saved tweet data? If not, lets get it.
if( $feed === false ){
$feed = $this->call_twitter();
}
$html = $this->build_html( $feed );
return $html;
}// protected function get_feed(){...}
protected function call_twitter(){
/* We need the following:
$feed = array(
'username' => '',
'friendly_name' => '',
'url' => ''
'tweets' => array(
array(
'html' => '',
'url' => '',
'time' => ''
),
array(
'html' => '',
'url' => '',
'time' => ''
)
)
);
*/
$feed = array();
// Get the tweets from Twitter.
$response = wp_remote_get( "http://api.twitter.com/1/statuses/user_timeline.json?screen_name={$this->name}&count=10&exclude_replies=false" );
// parse Twitter response into an array
if( !is_wp_error($response) && $response[ 'response' ][ 'code' ] == 200 ){
// Get tweets into an array.
$tweets_json = json_decode( $response['body'], true );
// Now update the array to store just what we need.
$feed[ 'username' ] = $tweets_json[ 0 ][ 'user' ][ 'screen_name' ];
$feed[ 'friendly_name' ] = $tweets_json[ 0 ][ 'user' ][ 'name' ];
$feed[ 'url' ] = 'https://twitter.com/' . $tweets_json[ 0 ][ 'user' ][ 'screen_name' ];
$feed[ 'tweets' ] = array();
foreach ( $tweets_json as $tweet ){
$my_tweet = array();
// Core info.
$my_tweet[ 'url' ] = 'http://twitter.com/#!/'. $feed[ 'username' ] .'/status/'. $tweet['id_str'];
// Message. Convert links to real links.
$pattern = '/http:(S)+/';
$replace = '<a href="${0}" target="_blank" rel="nofollow">${0}</a>';
$my_tweet[ 'html' ] = preg_replace( $pattern, $replace, $tweet['text'] );
//$my_tweet[ 'html' ] = $tweet['text'];
// Need to get time in Unix format.
$time = $this->twitter_time( $tweet[ 'created_at' ] );
//$time = date_parse( $time );
//$uTime = mktime($time['hour'], $time['minute'], $time['second'], $time['month'], $time['day'], $time['year']);
$my_tweet[ 'time' ] = $time;
array_push( $feed[ 'tweets' ], $my_tweet );
}
// Save our new transient, and update the backup.
set_transient( $this->transName, $feed, 60 * $this->cacheTime );
update_option( $this->backupName, $feed );
}
else{
// i.e. Fetching new tweets failed.
$feed = get_option( $this->backupName ); // False if there has never been data saved.
}
return $feed;
}
protected function build_html( $feed ){
$html = '';
$is_top = false;
if( $feed[ 'friendly_name' ] == 'Johnny Cupcakes' ){
$is_top = true;
}
ob_start();
include( plugin_dir_path( __FILE__ ) . '../html/feed.html' );
$html = ob_get_clean();
return $html;
}
}
?>
插件第一次构建html时(也就是说,当数据直接从twitter而不是从存储在本地数据库中的数据中提取时),一切都显示良好。然而,当我使用get_transient()来检索缓存的数据时,在一些推文上(哪个推文会产生这个错误,有多少推文拒绝运行会有所不同),我会得到以下错误:
Warning: Illegal string offset 'username' in /Applications/MAMP/htdocs/sites/wp-johnnycupcakes/wp-content/plugins/jc-twitter-widget/html/feed.html on line 12
feed.html的第12行是:
<h3><a target="_new" href="<?php echo $feed[ 'url' ]; ?>"> @<?php echo $feed[ 'username' ]; ?> </a></h3>
经过进一步的研究,在我的一些提要中,当我使用get_transient()时,返回的值似乎不再是数组,而是编码的字符串(我假设这是Wordpress在数据库中存储transient_values的编码约定)。字符串如下:
string(830) "a:4:{s:8:"username";s:15:"JHNYCPKS_London";s:13:"friendly_name";s:18:"Johnny Cupcakes UK";s:3:"url";s:35:"https://twitter.com/JHNYCPKS_London";s:6:"tweets";a:9:{i:0;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278196905350164480";s:4:"html";s:128:"Baked in USA long sleeve, Truffle and White Mens Basic Tee's are now back in stock come and grab them now while supplies last!!!";s:4:"time";s:11:"2 hours ago";}i:1;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278180246967173121";s:4:"html";s:121:"Put a pin on it! @ Johnny Cupcakes http://t.co/nxVSAG63";s:4:"time";s:11:"4 hours ago";}i:2;a:3:{s:3:"url";s:63:"http://twitter.com/#!/JHNYCPKS_London/status/278179975474053120";s:4:"html";s:161:"Big kid magnet came in today! "
当返回一个数组(从而成功显示提要)时,它看起来是这样的:
array(4) {
["username"]=>
string(15) "JHNYCPKS_Boston"
["friendly_name"]=>
string(20) "JohnnyCupcakesBoston"
["url"]=>
string(35) "https://twitter.com/JHNYCPKS_Boston"
["tweets"]=>
array(7) {
[0]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278204808756862976"
["html"]=>
string(139) "IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING! IT'S RAINING!"
["time"]=>
string(11) "2 hours ago"
}
[1]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278169219160489984"
["html"]=>
string(167) "Four #freshlybaked keychains were released this weekend! Which is your favorite? <a href="http://t.co/Xn16NsjU" target="_blank" rel="nofollow">http://t.co/Xn16NsjU</a>"
["time"]=>
string(11) "4 hours ago"
}
[2]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278137791391617025"
["html"]=>
string(29) "@thatkidTHILL good luck, man!"
["time"]=>
string(11) "6 hours ago"
}
[3]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/278137703281881088"
["html"]=>
string(96) "@dcachopa18 i don't think so, sorry! we'll let you know if we do. what size are you looking for?"
["time"]=>
string(11) "6 hours ago"
}
[4]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277888036237373440"
["html"]=>
string(188) "Only a few hours left! Spend $50, get a $10 gift card. Stop in or shop online. We close at 7 tonight! <a href="http://t.co/082T5jTf" target="_blank" rel="nofollow">http://t.co/082T5jTf</a>"
["time"]=>
string(12) "23 hours ago"
}
[5]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277786268274933760"
["html"]=>
string(135) "Here's the new Boston in-store! cc: @b3asTTw33ts <a href="http://t.co/soLoEYqv" target="_blank" rel="nofollow">http://t.co/soLoEYqv</a>"
["time"]=>
string(9) "yesterday"
}
[6]=>
array(3) {
["url"]=>
string(63) "http://twitter.com/#!/JHNYCPKS_Boston/status/277526406076968961"
["html"]=>
string(119) "What's everyone's favorite piece from this release?! The new Boston exclusive seems to be the hot ticket. #freshlybaked"
["time"]=>
string(9) "yesterday"
}
}
}
我对可能导致这种情况的原因有几个想法:
- 试图将过多数据存储到瞬态中
- 一些被拉入的字符扰乱了Wordpress将数据转换为字符串的方式,反之亦然
有没有人对这个问题有一些经验,可以为我指出纠正它的正确方向?
数组的串行化出现问题;您显示的示例编码字符串只是数组的部分串行化,因此它在某个地方出现了错误(串行化或保存到DB中)。
也许可以尝试自己串行化它(调用serialize()),对它进行base64编码,然后设置瞬态。在检索时,base64解码并取消序列化。如果问题出在WordPress/wpdb保存串行数组上,它可能会起作用。