Welcome!

Join our community of MMORPG enthusiasts and private server developers! By registering, you'll gain access to in-depth discussions on source codes, binaries, and the latest developments in MMORPG server files. Collaborate with like-minded individuals, explore tutorials, and share insights on building and optimizing private servers. Join us today and unlock the full potential of MMORPG server development!

Join Today!

[PHP]Generating cached XML

Joined
Aug 6, 2009
Messages
2,132
Reaction score
429
Location
USA (Fuck Yeah)
I had this playlist script for video player. Each time it was requested, it gather data from mysql and showed it. With requests every few minutes wasn't so bad until it became every few seconds.

MySQL process was literary jumping to 25% with each request. Each request returned about 500 rows :laugh:

SO to the point. If I wanna have cached XML playlist file I would do something like.


  • Check if cache file exists and is not older than hour.

  • If older then generate new

  • If not old, open it and show it' contents
That's it? Same as for template engine?
 
Add a timestamp to the XML. If the current timestamp in realtime is greater than the timestamp in the XML, then make a new XML.

//Get current XML time
$Time = get_xml_time(); //of course that function doesn't exist. You make it, and get the <time></time> from the XML file.
if(date() > $Time)
//Generate new XML

That could work?
 
use cache headers PHP Caching Headers

PHP:
<?php
$seconds_to_cache = 3600;
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";

header("Content-Type: text/xml");
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");

echo file_get_contents('path/to/file.xml');

edit: you can store mysql data in a session and pull from it every hour or the first time in the session


PHP:
<?php
session_start();

// check if we have the data. If so, check if it's time to get the data
if (!isset($_SESSION['xml_data']) || time() > $_SESSION['xml_expire'])
{
    // Set expire time to 1 hour:
    $_SESSION['xml_expire'] = strtotime('+1 hour')

    /*
     * Grab all xml data from SQL:
     */
    
    $_SESSION['xml_data'] = array();
    $statement = $db->query('SELECT * FROM table')
    while ($row = $statement->fetch_assoc())
    {
        foreach ($row as $col => $val)
        {
            $_SESSION['xml_data'][$col] = $val;
        }
    }
}

// Turn Associative Array into Readble XML
echo build_xml_from_assoc($_SESSION['xml_data']);
(Note that build_xml_from_assoc() doesn't really exist)


Last (and perhaps best) scenario:

IF you have a session full of mysql data already,
- Get one row from mysql, ordering by ID descending.
- if that id from sql is not equal to the last id in your session array,
- - reload mysql data
Convert associative array to XML data.


That will grab 1 row from mysql everytime, and all the rows the first time and any time the last key is different than it was the previous load.
 
Last edited:
Use memcached to cache SQL queries. Use pushing to sync diffs instead of an entire playlist. Use caching headers on the requests in polling to prevent page reloads from pulling a full copy from the server again. You can also use browser local storage to store the list and check for it on page load.

Don't store it in a session.
 
Use memcached to cache SQL queries. Use pushing to sync diffs instead of an entire playlist. Use caching headers on the requests in polling to prevent page reloads from pulling a full copy from the server again. You can also use browser local storage to store the list and check for it on page load.

Don't store it in a session.

memcache seems better. Does it store 1 entry for the file in memory to be shared across all users?
 
Must you use XML?

APC has exactly the capabilities you're looking for.

APC is more commonly used as an OPcode cache, so I would say memcached is more suitable in this situation. Although, there's no reason why you shouldn't use it considering numerous benchmarks have shown significant performance increases in comparison to memcached - that is, if you are storing data that are frequently accessed on a single web server. Besides, your web host (or yourself) should have an OPcode cache/accelerator installed on default already.

If memcached is not available to you (since it's not bundled with PHP), you could also utilise filemtime to check if your XML cache is stale. If it isn't stale and it is consistent with the database, call a touch function to update its last modification time. Perhaps you should also consider fine-tuning your MySQL configuration.
 
APC is more commonly used as an OPcode cache, so I would say memcached is more suitable in this situation. Although, there's no reason why you shouldn't use it considering numerous benchmarks have shown significant performance increases in comparison to memcached - that is, if you are storing data that are frequently accessed on a single web server. Besides, your web host (or yourself) should have an OPcode cache/accelerator installed on default already.

If I recall correctly, APC caches all IL, including variables when appropriate -- apc_store() is as much a first-class member in APC as opcode caching is, and seems like the most appropriate solution in addition to jMerliN's given that it accepts a name, value and ttl.
 
If I recall correctly, APC caches all IL, including variables when appropriate -- apc_store() is as much a first-class member in APC as opcode caching is, and seems like the most appropriate solution in addition to jMerliN's given that it accepts a name, value and ttl.

Yeap. Indeed, which is why I said there's no reason why you shouldn't use it :) There's no doubt that it has a greater advantage over memcached in terms of performance. Heck, it's even being integrated into PHP 6 if I'm not mistaken.

The reason why I say memcached is in fact more oriented towards user variable caching is because it separates the user and opcode cache. It's really good at preventing fragmentation. On the contrary (not too sure about this), APC tends to have issue with fragmentation (in the opcode cache) especially if you have a low TTL - due to R/W from the user cache. You'll require some knowledge in configuring APC for it to achieve your desired results. I personally experienced this back when I was managing a web host server.

Besides, there's no reason why you shouldn't use one or the other. You could use both and like I said, most web host should have an opcode cache installed anyways.
 
Back