我的php项目使用reddit JSON api来获取当前页面提交的标题。
现在,我每次加载页面时都会运行一些代码,即使没有真正的API限制,我也会遇到一些问题。
我想以某种方式将提交的标题存储在本地。你能推荐最好的方法吗?该网站在appfog上运行。你有什么推荐的?
这是我当前的代码:
<?php
/* settings */
$url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$reddit_url = 'http://www.reddit.com/api/info.{format}?url='.$url;
$format = 'json'; //use XML if you'd like...JSON FTW!
$title = '';
/* action */
$content = get_url(str_replace('{format}',$format,$reddit_url)); //again, can be xml or json
if($content) {
if($format == 'json') {
$json = json_decode($content,true);
foreach($json['data']['children'] as $child) { // we want all children for this example
$title= $child['data']['title'];
}
}
}
/* output */
/* utility function: go get it! */
function get_url($url) {
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,1);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
?>
谢谢!
发布于 2012-12-12 01:23:18
引言
以下是您的代码的修改版本
$url = "http://stackoverflow.com/";
$loader = new Loader();
$loader->parse($url);
printf("<h4>New List : %d</h4>", count($loader));
printf("<ul>");
foreach ( $loader as $content ) {
printf("<li>%s</li>", $content['title']);
}
printf("</ul>");
输出
新列表:7
乔尔·斯波尔斯基和杰夫·阿特伍德的
Simple Demo
问题所在
我在这里看到了一些你想要实现的东西,即
我想将提交的标题存储在本地,现在我正在运行一些代码,每次加载页面时都会运行
据我所知,你需要一个简单的缓存副本的数据,这样你就不必一直加载网址。
简单解决方案
您可以使用的一个简单的缓存系统是memcache。
示例A
$url = "http://stackoverflow.com/";
// Start cache
$m = new Memcache();
$m->addserver("localhost");
$cache = $m->get(sha1($url));
if ($cache) {
// Use cache copy
$loader = $cache;
printf("<h2>Cache List: %d</h2>", count($loader));
} else {
// Start a new Loader
$loader = new Loader();
$loader->parse($url);
printf("<h2>New List : %d</h2>", count($loader));
$m->set(sha1($url), $loader);
}
// Oupput all listing
printf("<ul>");
foreach ( $loader as $content ) {
printf("<li>%s</li>", $content['title']);
}
printf("</ul>");
示例B
您可以使用Last Modification Date
作为缓存键,以便仅在修改文档时才保存新副本
$headers = get_headers(sprintf("http://www.reddit.com/api/info.json?url=%s",$url), true);
$time = strtotime($headers['Date']); // get last modification date
$cache = $m->get($time);
if ($cache) {
$loader = $cache;
}
因为您的类实现了JsonSerializable
,所以您可以对结果进行json编码,还可以将其存储在MongoDB或MySQL之类的数据库中
$data = json_encode($loader);
// Save to DB
使用的类
class Loader implements IteratorAggregate, Countable, JsonSerializable {
private $request = "http://www.reddit.com/api/info.json?url=%s";
private $data = array();
private $total;
function parse($url) {
$content = json_decode($this->getContent(sprintf($this->request, $url)), true);
$this->data = array_map(function ($v) {
return $v['data'];
}, $content['data']['children']);
$this->total = count($this->data);
}
public function getIterator() {
return new ArrayIterator($this->data);
}
public function count() {
return $this->total;
}
public function getType() {
return $this->type;
}
public function jsonSerialize() {
return $this->data;
}
function getContent($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
}
发布于 2012-12-10 18:50:10
我不确定你的问题到底是什么,但首先会想到的是:
foreach($json['data']['children'] as $child) { // we want all children for this example
$title= $child['data']['title'];
}
您确定要覆盖$title
吗?实际上,这将只保留最后一个$child
标题。
现在,来回答你的问题。我假设您正在寻找某种机制来缓存所请求的URL的内容,这样您就不必每次都重新发出请求,对吗?我没有任何使用appFog的经验,只有orchestra.io的经验,但我相信他们在写文件方面也有同样的限制,因为你只能写临时文件。
我的建议是将(已处理的)响应缓存在以下任一项中:
共享内存
您可以使用URL +参数的散列作为查找键,在get_url()
中执行此检查将意味着您不需要更改代码的任何其他部分,并且只需要~3LOC。
发布于 2012-12-16 18:32:07
在此之后:
if($format == 'json') {
$json = json_decode($content,true);
foreach($json['data']['children'] as $child) { // we want all children for this example
$title = $child['data']['title'];
}
}
}`
然后将其存储在json文件中并将其转储到本地文件夹网站路径中
$storeTitle = array('title'=>$title)
$fp = fopen('../pathToJsonFile/title.json'), 'w');
fwrite($fp, json_encode($storeTitle));
fclose($fp);
然后,您可以在下次调用json文件,对其进行解码,并将标题提取到一个变量中以供使用。
https://stackoverflow.com/questions/13773987
复制相似问题