I have a php code that automatically generates an RSS feed XML file. Now I have my pages which are in a folder. I read them out with simple php to generate title, links, description... that all goes fine and the code works great. But when I try to get the last timestamp of the file itself I get errors. I really can't figure out why the code gives errors.
<?php
$rssfeed = "<?xml version='1.0' encoding='ISO-8859-1'?>
<rss version='2.0'>
<channel>
<title>My RSS feed</title>
<link>http://" . $_SERVER['HTTP_HOST'] . "/</link>
<description>This is an example RSS feed</description>
<language>en-us</language>
<copyright>Copyright (C) 2009 mywebsite.com</copyright>
";
$links = scandir('../pages/');
$links = array_diff($links, array('.', '..', 'subpages', 'protected'));
foreach($links as $link){
$descr = file_get_contents('../description/' . $link);
$descr = str_replace(array('\\'), array(''), $descr);
$pub = date ('F d Y H:i:s.', filemtime($link));
$rssfeed .= "<item>
<title>".$link."</title>
<description>".$descr."</description>
<link>http://" . $_SERVER['HTTP_HOST'] . "/index.php?p=".$link."</link>
<pubDate>".$pub."</pubDate>
</item>";
}
$rssfeed .= "</channel></rss>";
file_put_contents("../RSSfeed.xml", $rssfeed, LOCK_EX);
?>
this is the error I get:
Warning: filemtime(): stat failed for 01Home in C:\Program Files\EasyPHP-DevServer-13.1VC9\data\localweb\admin\rss.php on line 35
(localhost on a easyphp server for testing)
Related
How can I get the contest logo and start date from this RSS feed? I can get the dc:modified child for example but always get a blank for anything from dc:dataset.
My code:
$feed_url = 'https://www.website.com/?call_custom_simple_rss=1&csrp_post_type=contest&csrp_posts_per_page=2&csrp_show_meta=1';
$feed = file_get_contents($feed_url);
$rss = simplexml_load_string($feed);
foreach($rss->channel->item as $entry) {
echo $entry->children("dc", true)->modified . "<br>";
echo $entry->children("dc", true)->dataset->contest_logo . "<br>";
echo $entry->children("dc", true)->dataset->start_date . "<br>";
}
The RSS feed:
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:wp="http://wordpress.org/export/1.2/" xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/" version="2.0">
<channel>
<title>RSS Title</title>
<description>A website</description>
<lastBuildDate>Wed, 17 Feb 2021 15:03:03 +0000</lastBuildDate>
<item>
<title>
<![CDATA[ Photography Awards ]]>
</title>
<link>
<![CDATA[ /contests/photography-awards/ ]]>
</link>
<pubDate>Mon, 11 Jan 2021 13:52:27 -0600</pubDate>
<dc:identifier>619116</dc:identifier>
<dc:modified>2021-02-09 07:50:10</dc:modified>
<dc:created unix="1610373147">2021-01-11 13:52:27</dc:created>
<dc:dataset>
<contest_logo>
<![CDATA[ 619130 ]]>
</contest_logo>
<start_date>
<![CDATA[ 20210110 ]]>
</start_date>
</dc:dataset>
</item>
</channel>
</rss>
The contest_logo and start_date are in the empty namespace. You have to switch back. Additionally it is not good to reply on namespace prefixes defined in the document. Use the namespace URI (for example defined as mapping array in your code).
$rss = simplexml_load_string($feed);
$xmlns = [
'dc' => 'http://purl.org/dc/elements/1.1/'
];
foreach($rss->channel->item as $entry) {
echo $entry->children($xmlns['dc'])->modified . "<br>";
echo $entry->children($xmlns['dc'])->dataset->children('')->contest_logo . "<br>";
echo $entry->children($xmlns['dc'])->dataset->children('')->start_date . "<br>";
}
Output:
2021-02-09 07:50:10<br>
619130
<br>
20210110
<br>
In DOM you would register an alias on the Xpath processor and use it in the expressions. Here is a demo:
$document = new DOMDocument();
$document->loadXML($feed);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
foreach ($xpath->evaluate('/rss/channel/item') as $entry) {
echo $xpath->evaluate('string(dc:modified)', $entry). "<br>";
echo $xpath->evaluate('string(dc:dataset/contest_logo)', $entry). "<br>";
echo $xpath->evaluate('string(dc:dataset/start_date)', $entry). "<br>";
}
Another alternative - use xpath:
echo $rss->xpath('//dc:dataset/contest_logo')[0] . "\r\n";
echo $rss->xpath('//dc:modified')[0] . "\r\n";
echo $rss->xpath('//start_date')[0] . "\r\n";
Output:
619130
2021-02-09 07:50:10
20210110
<?php
include 'classes/db.connect.php';
if (isset($_GET['user'])) {
if($blog->blog_check($_GET['user'])) {
$username = strip_tags($_GET['user']);
} else {
http_response_code(404); include('html/blogs/404.html'); die;
}
} else {
http_response_code(404); include('html/blogs/404.html'); die;
}
$current_page = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$url = $blog->get_blogger_branding($username, 'gravurl');
$img = 'assets/blogs/images/'.$_GET['user'].'.png';
file_put_contents($img, file_get_contents($url));
$fbimg = 'https://afpayday.com/assets/blogs/images/'.$_GET['user'].'.png';
header('Content-Type: application/rss+xml');
echo '<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>'.ucfirst($blog->get_blogger_branding($username, "fname")).'\'s Payday Blog</title>
<description>Learn about affiliate marketing and affiliate product reviews.</description>
<link>https://afpayday.com/'.$username.'</link>
<copyright>Copyright 2020 Affiliate Payday</copyright>
<language>en-us</language>
<managingEditor>admin#afpayday.com (Bruce Bates)</managingEditor>
<pubDate>Sun, 23 Feb 2020 09:50:44 -0700</pubDate>
<webMaster>admin#afpayday.com (Bruce Bates)</webMaster>
<atom:link href="https://afpayday.com/'.$username.'/rss/" rel="self" type="application/rss+xml" />
<image>
<url>'.$fbimg.'</url>
<title>'.ucfirst($blog->get_blogger_branding($username, "fname")).'\'s Payday Blog</title>
<link>https://afpayday.com/'.$username.'</link>
<description>'.ucfirst($blog->get_blogger_branding($username, "fname")).'\'s Photo</description>
<width>144</width>
<height>144</height>
</image>
<item>
<title>Test</title>
<guid>https://afpayday.com/'.$username.'</guid>
</item>
</channel>
</rss>
';
?>
According to the w3 validator my feed is correctly coded. https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fafpayday.com%2Fviraladmin%2Frss%2F
However browsers are not treating it as I would expect.
Firefox tries to download the feed as a file.
Chrome, Opera, and Edge show the feed as code instead of displaying it as a document tree which is what I normally see when viewing an RSS feed.
Only Internet Explorer seems to be handling it properly and showing the "would you like to subscribe to this feed" option.
The feed is here: https://afpayday.com/viraladmin/rss/
I would expect it to look more like https://www.feedforall.com/sample.xml in a browser
What am I doing wrong?
I have a set of articles in database I want to add their content to a file located in my project named rss.xml using the xml format.
This is the xml file from https://developers.facebook.com/docs/instant-articles/publishing/setup-rss-feed.
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>News Publisher</title>
<link>http://www.example.com/</link>
<description>
Read our awesome news, every day.
</description>
<language>en-us</language>
<lastBuildDate>2014-12-11T04:44:16Z</lastBuildDate>
<item>
<title>This is an Instant Article</title>
<link>http://example.com/article.html</link>
<guid>2fd4e1c67a2d28fced849ee1bb76e7391b93eb12</guid>
<pubDate>2014-12-11T04:44:16Z</pubDate>
<author>Mr. Author</author>
<description>This is my first Instant Article. How awesome is this?</description>
<content:encoded>
<!doctype html>
<html lang="en" prefix="op: http://media.facebook.com/op#">
<head>
<meta charset="utf-8">
<link rel="canonical" href="http://example.com/article.html">
<meta property="op:markup_version" content="v1.0">
</head>
<body>
<article>
<header>
<!— Article header goes here -->
</header>
<!— Article body goes here -->
<footer>
<!— Article footer goes here -->
</footer>
</article>
</body>
</html>
</content:encoded>
</item>
</channel>
</rss>
This is how far I got in my php:
$crud = new ArticleController();
$file = 'rss.xml'; //open the file
$xml = simplexml_load_file($file);
$channel = $xml->channel; //get channel to add item to
$list=$crud->getAll(); //Returns all articles in database
$item = $channel->addChild('item');
$item->addChild('title', 'a gallery');
$item->addChild('pubDate', '12/12/2017');
$item->addChild('description', 'something');
$content = $item->addChild('content:encoded');
$html = $content->addChild('html');
$xml->asXML($file); //write to file
I'm not going far since my code is returning already a lot of warnings and errors such :
Warning: simplexml_load_file(): rss.xml:25: parser error : Opening and ending tag mismatch: meta line 24 and head in file.php on line 153
Fatal error: Call to a member function children() on a non-object in /var/www/html/pfe2017/controller/ArticleController.php on line 156
Can anyone please help explaining how to accomplish the desired outcome with providing examples?
According to RSS Feeds for Instant Articles:
Remember to escape all HTML content by wrapping it within a CDATA section.
So, just wrap the HTML content of content:encoded with <![CDATA[ and ]]>:
<content:encoded><![CDATA[
<!doctype html>
...
</html>
]]></content:encoded>
Also:
$content = $item->addChild('content:encoded');
$html = $content->addChild('html');
The code above produces the following XML: <encoded><html/></encoded>
Change those lines with something like these:
$content = $item->addChild('content:encoded', null, 'http://purl.org/rss/1.0/modules/content/');
$base = dom_import_simplexml($content);
$docOwner = $base->ownerDocument;
$base->appendChild($docOwner->createCDATASection('<html>Some HTML</html>'));
to produce the following valid XML element:
<content:encoded><![CDATA[<html>Some HTML</html>]]></content:encoded>
For a reference, please, have a look at:
How to write CDATA using SimpleXmlElement?
SimpleXMLElement::addChild
I solved it my self here is the code below:
$rssfeed = '<?xml version="1.0" encoding="ISO-8859-1"?>';
$rssfeed .= '<rss version="2.0">';
$rssfeed .= '<channel>';
$rssfeed .= '<title>My RSS feed</title>';
$rssfeed .= '<link>my link</link>';
$rssfeed .= '<description>something</description>';
$rssfeed .= '<language>en-us</language>';
$rssfeed .= '<copyright>Copyright (C) 2017</copyright>';
foreach ($list as $l) {
$rssfeed .= '<item>';
$rssfeed .= '<title>' . $l['titre'] . '</title>';
$rssfeed .= '<description>' . $l['contenu'] . '</description>';
$rssfeed .= '<link>' . "my link" . '</link>';
$rssfeed .= '<pubDate>' . date("D, d M Y H:i:s O", strtotime($l['date_de_creation'])) . '</pubDate>';
$rssfeed .= '</item>';
}
$rssfeed .= '</channel>';
$rssfeed .= '</rss>';
$handle = fopen("../rss.xml", "w+");
fclose($handle);
$myfile = fopen("../rss.xml", "w");
fwrite($myfile, $rssfeed);
fclose($myfile);
I am new in php nd want to help in generating rss feed. i have a db with name "test123" having fields Id, Name, Address, Designation and Text. Here is my code for rss feed`
<?php
function connect() {
return new PDO('mysql:host=localhost;dbname=test123', 'root', '', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}
$pdo = connect();
// posts *******************************
$sql = 'SELECT * FROM form ORDER BY id DESC';
$query = $pdo->prepare($sql);
$query->execute();
$rs_post = $query->fetchAll();
// The XML structure
$data = '<?xml version="1.0" encoding="UTF-8" ?>';
$data .= '<rss version="2.0">';
$data .= '<channel>';
$data .= '<title>PACRA Rss Feed</title>';
$data .= '<link>http://www.pacra.com</link>';
$data .= '<description>Pacra Pakistan</description>';
foreach ($rs_post as $row) {
$data .= '<item>';
$data .= '<title>'.$row['Name'].'</title>';
$data .= '<link>'.$row['Address'].'</link>';
$data .= '<description>'.$row['Text'].'</description>';
$data .= '</item>';
}
$data .= '</channel>';
$data .= '</rss> ';
header('Content-Type: application/xml');
echo $data;
?>`
Problem is that when i run that code it show an error message "Opening and Ending Tag mismatch"
Here is the image of error
Image Link
It might be the header, I use the following in my PHP generated RSS feeds: header('Content-type: text/xml; charset=UTF-8');
And escape your <title> and <description> with CDATA.
Did you validate your feed using the RSS validator? https://validator.w3.org/feed/
Also my structure is a bit different:
<?xml version="1.0" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="http://www.website.com" rel="self" type="application/rss+xml" />
<title>RSS Title</title>
<link>http://www.website.com</link>
<description>Description</description>
<language>en</language>
<managingEditor>Name</managingEditor>
<webMaster>mail#mail.com</webMaster>
<item>
<pubDate>Wed, 02 Oct 2015 15:00:00 +0200</pubDate>
<title><![CDATA[Here the title]]></title>
<link>http://www.website.com/page</link>
<guid>http://www.website.com/page</guid>
<description><![CDATA[Here the content]]></description>
</item>
<item>
<pubDate>Wed, 02 Oct 2015 15:00:00 +0200</pubDate>
<title><![CDATA[Here the title2]]></title>
<link>http://www.website.com/page2</link>
<guid>http://www.website.com/page2</guid>
<description><![CDATA[Here the content2]]></description>
</item>
</channel>
</rss>
Trying to parse out lat/lon from a google maps rss feed:
$file = "http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=1&jsv=327b&msa=0&output=georss&msid=217909142388190116501.000473ca1b7eb5750ebfe";
$xml = simplexml_load_file($file);
$loc = $xml->channel->item;
echo $loc[0]->title;
echo $loc[0]->point;
The title shows up alright, but point gives me nothing. Each node looks like this:
<item>
<guid isPermaLink="false">0004740950fd067393eb4</guid>
<pubDate>Sun, 20 Sep 2009 21:47:49 +0000</pubDate>
<title>Big Wong King Restaurant</title>
<description><![CDATA[<div dir="ltr">$4.99 full meals!</div>]]></description>
<author>neufuture</author>
<georss:point>
40.716236 -73.998413
</georss:point>
<georss:elev>0.000000</georss:elev>
</item>
<?php
$file = "http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=1&jsv=327b&msa=0&output=georss&msid=217909142388190116501.000473ca1b7eb5750ebfe";
$xml = simplexml_load_file($file);
$loc = $xml->channel->item;
foreach ($loc->children('http://www.georss.org/georss') as $geo) {
echo $geo;
}
?>