Creating A PHP Sitemap XML Script - php

I have a database driven website that I add to every day & I want to make an xml sitemap for google with php but I'm really unsure of how to do this. Using the code that I'm used to I created this:
<?php
$get_articles_sql = "SELECT * FROM articles ORDER BY added DESC";
$get_articles_res = mysqli_query($con, $get_articles_sql);
while($article = mysqli_fetch_assoc($get_articles_res)){
$article_id = $article["id"];
$article_title = $article["title"];
$article_added = $article["added"];
$article_date = date('Y-M-D', strtotime($article_added));
$article_url_title = preg_replace('/[^a-zA-Z0-9_ %\[\]\.\(\)%&-]/s', '', $article_title);
$article_url_title = strtolower(str_replace(" ","-",$article_url_title));
$list_articles .= "
<url>
<loc>http://www.website.com/article.php?id=$article_id&title=$article_url_title</loc>
<lastmod>$article_date</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
";
?>
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.website.com</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<?php echo $list_articles; ?>
</urlset>
However, this returns an error on the <?xml line. Is there a correct way of doing it using the code method that I'm using?

Your server probably has short tags enabled which causes the <? in the XML declaration to throw a parse error. The easiest work around is to just echo that line out.
echo '<?xml version="1.0" encoding="UTF-8"?>'
?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
It also looks like you're missing the closing bracket to your while loop but I am assuming that is merely a typo.

Related

How to add string to sitemap.xml before </urlset> closing tag, in php

after hours of looking for solution, i could not find any that works or suits my issue.
Basically, i have dynamic website, that generates new pages and i want to add to it the ability to add that new page to the sitemap.xml
When i use the :
file_put_contents("$sitemap_file", $string_to_add, FILE_APPEND);
it will add the $string_to_add at the end of the sitemap.xml, after the /urlset tag.
Is there any way to add this string before the /urlset tag ?
My code at the moment :
$date_mod = date('Y-m-d');
$string = "
<url>
<loc>https://www.mywebsite.com$internal_link</loc>
<lastmod>$date_mod</lastmod>
<changefreq>monthly</changefreq>
</url>";
file_put_contents("$root/sitemap.xml", $string, FILE_APPEND);
you can try something like below using SimpleXML:
$date_mod = date('Y-m-d');
$string = "
<url>
<loc>https://www.mywebsite.com$internal_link</loc>
<lastmod>$date_mod</lastmod>
<changefreq>monthly</changefreq>
</url>";
$xml = simplexml_load_file("$root/sitemap.xml");
$xml->addChild($string);
file_put_contents("$root/sitemap.xml", $xml->asXML());
This will put <url> inside <urlset> tag, hopefully.
Just use SimpleXML:
// You can also do
// $xmlStr= file_get_contents('sitemap.xml');
$xmlStr=<<<XML
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://domain.fake/link1.html</loc>
<priority>1.0</priority>
</url>
<url>
<loc>http://domain.fake/link2.html</loc>
<priority>0.99</priority>
</url>
</urlset>
XML;
// Create the SimpleXML object from the string
$xml = simplexml_load_string($xmlStr);
// add an <url> child to the <urlset> node
$url = $xml->addChild("url");
// add the <loc> and <priority> children to the <url> node
$url->addChild("loc", "http://domain.fake/link2.html");
$url->addChild("priority", 0.98);
// get the updated XML string
$newXMLStr = $xml->asXML();
//write it to the sitemap.xml file
file_put_contents('sitemap.xml',$newXMLStr);

php PDO fetchAll with foreach not working

I'm having some problems with PDO selecting from Database in order to generate dynamic Sitemap file based on articles (essentially pages). PHP is not throwing any errors as I don't see any errors in the error log. Here is the code.
SELECT STATEMENT SNIPPET
$q = $db->prepare("SELECT * FROM articles ORDER BY aid ASC");
$r = $q->fetchAll(PDO::FETCH_ASSOC);
FOR EACH SNIPPET + XML
foreach($r as $row) {
$format_date = date('Y-m-d', $row['date']);
$format_slug = strtolower($row['slug']);
echo '
<url>
<loc>'.$format_slug.'</loc>
<lastmod>'.$format_date.'</lastmod>
<changefreq>monthly</changefreq>
</url>
';
}
XML DATA BEFORE "FOREACH"
echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc></loc>
<lastmod>2017-01-27</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>contact-us</loc>
<lastmod>2017-01-27</lastmod>
<changefreq>yearly</changefreq>
</url>
';
XML DATA AFTER "FOREACH"
echo '</urlset>';
And I am using proper PHP header for the XML output at the very top of the page which is
header('Content-Type: text/xml');
So ones I navigate to the Sitemap url, the predefined data in the echo statements is returned, in this case the 2 data snippets in the BEFORE "FOREACH" part and of course the AFTER "FOREACH" is returned.
However for some odd reason no data is being fetched from the database even truth the script seems to work. Am I missing something?
You need to execute the statement.
$q = $db->prepare("SELECT * FROM articles ORDER BY aid ASC");
$q->execute();
$r = $q->fetchAll(PDO::FETCH_ASSOC);
Alternatively you can use PDO::query http://php.net/manual/en/pdo.query.php.
Have you forgotten to call Execute on statement?

cannot write to xml properly

I have the following problem. I am trying to create a new item in an xml file but I think something wrong with my code here is an xml file
<?xml version="1.0" encoding="iso-8859-1"?>
<urls>
<url>
<link>http://google.com</link>
</url>
</urls>
I just want to add another url using PHP here is how I am trying to do it
// Open and parse the XML file
$xml = simplexml_load_file("urls.xml");
// Create a child in the first topic node
$child = $xml->url[0]->addChild("url");
// Add the text attribute
$child->addAttribute("link", $url);
// Display the new XML code
echo $xml->asXML();
// Store new XML code in questions.xml
$xml->asXML("urls.xml");
But instead of another URL I am getting only link tag. Sorry I am new to XML. What could be wrong?
try this, parse with DOM
$doc = new DOMDocument();//DOMDocument()
if(file_exists("urls.xml"))
$doc->load("article.xml");
$racine=$doc->documentElement;
$racine1=$doc->createElement("URL");//create element URL
$link=$doc->createElement("link"); //reate element link
$racine1->appendChild($link); //add element link to element URL
$textlink=$doc->createTextNode("text");// create textnode with value "text"
$link->appendChild($textlink); // add textnode to element link
$racine->appendChild($racine1); // add element URl to Racine URLS
$doc->appendChild($racine);
$xml=$doc->saveXML();
$doc->save("urls.xml");
header("content-type: text/xml");
This isn't working because you're telling it to do the wrong thing.
If you have this:
<?xml version="1.0" encoding="iso-8859-1"?>
<urls>
<url>
<link>http://google.com</link>
</url>
</urls>
And you want this:
<?xml version="1.0" encoding="iso-8859-1"?>
<urls>
<url>
<link>http://google.com</link>
</url>
<url>
<link>http://stackoverflow.com</link>
</url>
</urls>
But you're telling it to do this:
<?xml version="1.0" encoding="iso-8859-1"?>
<urls>
<url>
<link>http://google.com</link>
<url link="http://www.stackoverflow.com" />
</url>
</urls>
Try the following code instead:
$xml = simplexml_load_file("urls.xml");
// Create a child in the first topic node
$child = $xml->urls[0]->addChild("url");
$child->addChild("link", $url);
// Display the new XML code
echo $xml->asXML();
// Store new XML code in questions.xml
$xml->asXML("urls.xml");

How to make xml out from text inside a text file in php

How to make xml out from text inside a text file in php?
I have a code but it brings me error "Extra content at the end of the document".
Below is my code:
<?php
header('Content-Type: application/xml');
$lines = file('file.txt');
echo '<?xml version="1.0" encoding="UTF-8"?>';
foreach($lines as $line){
$output = '<url><loc>http://example.com/'.$line.'.html</loc></url>';
echo $output;
}
here is example text file:
page1
page2
page3
page4
sample output:
<url>
<loc>http://example.com/page1.html</loc>
</url>
<url>
<loc>http://example.com/page2.html</loc>
</url>
<url>
<loc>http://example.com/page3.html</loc>
</url>
<url>
<loc>http://example.com/page4.html</loc>
</url>
I will need to use these for sitemap.xml
The XML error "Extra content at the end of the document" is quite simple. By definition, a valid XML DOM must have one, and only one, single root note, which contains the entire dataset. You don't have this. Your output is:
<?xml version="1.0"?>
<url>
<loc>http://example.com/page1.html</loc>
</url>
<url>
<loc>http://example.com/page2.html</loc>
</url>
<url>
<loc>http://example.com/page3.html</loc>
</url>
<url>
<loc>http://example.com/page4.html</loc>
</url>
Whereas valid XML would be:
<?xml version="1.0" encoding="UTF-8"?>
<sitemap>
<url>
<loc>http://example.com/page1.html</loc>
</url>
<url>
<loc>http://example.com/page2.html</loc>
</url>
<url>
<loc>http://example.com/page3.html</loc>
</url>
<url>
<loc>http://example.com/page4.html</loc>
</url>
</sitemap>
So the simple fix in your case would be:
header('Content-type: application/xml');
echo '<?xml version="1.0" encoding="UTF-8"?>
<sitemap>';
$lines = file(
'file.txt',
//do not line-breaks to XML values, and skip empty values, to avoid empty tags
FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES
);
foreach ($lines as $line)
{
echo '<url><loc>http://example.com/', $line, '.html'</loc></url>';
}
echo '</sitemap';
But really, I'd recommend you think about how to best structure your DOM, and how you can use DOM parsers to reliably construct the markup. And after that, I'd strongly recommend you write the file to disk, instead of generating it every single time you need it.
You can use file_put_contents in php to write into file

Creating an XML sitemap with PHP

I'm trying to create a sitemap that will automatically update. I've done something similiar with my RSS feed, but this sitemap refuses to work. You can view it live at http://designdeluge.com/sitemap.xml I think the main problem is that its not recognizing the PHP code. Here's the full source:
<?php
include 'includes/connection.php';
header("Content-type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8" ?>';
?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84 http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">
<url>
<loc>http://designdeluge.com/</loc>
<lastmod>2010-04-20</lastmod>
<changefreq>weekly</changefreq>
<priority>1.00</priority>
</url>
<url>
<loc>http://designdeluge.com/about.php</loc>
<lastmod>2010-04-20</lastmod>
<changefreq>never</changefreq>
<priority>0.5</priority>
</url>
<?php
$entries = mysql_query("SELECT * FROM Entries");
while($row = mysql_fetch_assoc($entries)) {
$title = stripslashes($row['title']);
$date = date("Y-m-d", strtotime($row['timestamp']));
echo "
<url>
<loc>http://designdeluge.com/".$title."</loc>
<lastmod>".$date."</lastmod>
<changefreq>never</changefreq>
<priority>0.8</priority>
</url>";
} ?>
</urlset>
The problem is that the dynamic URL's (e.g. the ones pulled from the DB) aren't being generated and the sitemap won't validate. Thanks!
EDIT: Right now, I'm just trying to get the code itself working. I have it set up as a PHP file on my local testing server. The code above is being used. Right now, nothing displays nothing on screen or in the source. I'm thinking I made a syntax error, but I can't find anything. Any and all help is appreciated!
EDIT 2: Ok, I got it sorted out guys. Apparently, I had to echo the xml declaration with PHP. The final code is posted above. Thanks for your help!
If you take a look at the sitemap.xml that's generated (using view source, in your browser, for example), you'll see this :
<?php header('Content-type: text/xml'); ?>
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:xsi="http:/
...
The <?php, present in that output, shows that PHP code is not interpreted.
This is probably because your webserver doesn't recognize .xml as an extension of files that should contain PHP code.
At least two possible solutions :
Re-configure your server, so XML files go through the PHP interpreter (might not be such a good idea : that can cause problems with existing files ! )
Change the extension of your sitemap, to sitemap.php for example, so it's interpreted by your server.
I would add another solution :
Have a sitemap.php file, that contains the code
And use a RewriteRule so the sitemap.xml URL actually points to the sitemap.php file
With that, you'll have the sitemap.xml URL, which is nice (required ? ), but as the code will be in sitemap.php, it'll get interpreted.
See Apache's mod_rewrite.
The simplest solution is to add to your apache .htaccess file the following line after RewriteEngine On
RewriteRule ^sitemap\.xml$ sitemap.php [L]
and then simply having a file sitemap.php in your root folder that would be normally accessible via http://yoursite.com/sitemap.xml, the default URL where all search engines will firstly search.
The file sitemap.php shall start with
<?php header('Content-type: application/xml; charset=utf-8') ?>
<?php echo '<?xml version="1.0" encoding="UTF-8"?>' ?>
I've used William's code (thanks) and with a few small modifications it worked for me.
I think the line:
header("Content-type: text/xml");
should be the second line after the top <?php
Incidentally, just a small point to anyone else that copies it, but there is a single space character before the <?php in the first line - if you inadvertantly copy it as I did, you will spend a bit of time trying to figure out why the code won't work for you!
I had to tweak the MySql select statement a little bit too.
Finally, in the output, I have used a variable $domain so that this piece of code can be used as a template without the need to think about it (provided you use the same table name each time). The variabe is added to the connectdb.php file which is included to connect to the database.
Here is my working version of the William's code:
<?php
header("Content-type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8" ?>';
include 'includes/connectdb.php';
?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84 http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">
<url>
<loc>http://www.DOMAIN.co.uk/</loc>
<priority>1.00</priority>
</url>
<?php
$sql = "SELECT * FROM pages WHERE onshow = 1 ORDER BY id ASC";
$result = mysql_query($sql,$conn);
while($row = mysql_fetch_array($result))
{
$filename = stripslashes($row['filename']);
?>
<url>
<loc>http://www.<?php echo "$domain"; ?>/<?php echo "$filename" ?></loc>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
<?php } ?>
</urlset>
Here is the easiest way to creating and updating sitemap.xml file.
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
require_once('database.php');
$sitemapText = '<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>http://ajkhub.com/</loc>
<lastmod>2021-08-18T18:32:09+00:00</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>http://ajkhub.com/includes/about.php</loc>
<lastmod>2021-08-18T18:32:09+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>http://ajkhub.com/includes/privacy-policy.php</loc>
<lastmod>2021-08-18T18:32:09+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>http://ajkhub.com/includes/termsandcondition.php</loc>
<lastmod>2021-08-18T18:32:09+00:00</lastmod>
<priority>0.80</priority>
</url>';
$sql = "SELECT * FROM page ORDER BY id DESC LIMIT 4";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
$sitemapText .= ' <url>
<loc>'.$actual_link."/".$row['page'].'</loc>
<lastmod>'.date(DATE_ATOM,time()).'</lastmod>
<priority>0.80</priority>
</url>';
}
}
$sitemapText .= '</urlset>';
$sitemap = fopen("sitemap.xml", "w") or die("Unable to open file!");
fwrite($sitemap, $sitemapText);
fclose($sitemap);

Categories