Showing newest posts with label code. Show older posts
Showing newest posts with label code. Show older posts

2.27.2010

Export from Wordpress blog and Import to Blogger

This script exports your posts and categories from your locally hosted Wordpress blog and imports them into a new Blogger blog online. The script is based on the Blogger examples for working with PHP and blog data.

Code to export from hosted Wordpress blog and import to Blogger at github

You need to have the Zend Framework up and running on your system as it contains all the GData libraries for working with Google data in PHP. This script doesn't use any of the MVC, so you just need to have the files somewhere that you can require them. More on Zend Framework here.

You need to edit line 8 to point to the path of your Zend Framework. You also need to update the database connection variables right below that to match your wordpress blog.

Some caveats:

  • Blogger can only import 50 blog posts per day before tripping some anti-spam protection. So the SQL "limit" clause around line 322 will need to be adjusted. It is set to get the first 50 posts and publish them.
  • Wordpress "categories" become Blogger "labels"
  • Blogger forces any imported comments to the blog posts to originate from you, the author, of the blog.  So I have omitted these from my script, figuring it would look crazy to be talking to myself.  You could hack this script to add those back in.  

What's great about Blogger is that you can create a new test blog and run this script, which allows you to select which Blogger blog you wish to update and go from there.

The usage is:

php xfer_to_blogger.php --user=email@email.com --pass=password

The email and password here are the ones you used in setting up your Blogger account.

Let me know how you make out and if you have any suggestions for the code.
read more...

7.20.2007

Alpha Wordpress Plugin for Delicious with Zend Framework's Zend_Service_Delicious

I have Wordpress set up on PHP5. While Wordpress is largely a PHP4 entity, I wanted to see if it could play nicely with the Zend Framework, which is a PHP5-only entity. With some careful fiddling, it works pretty well.

With my Zend Framework code set up in my PHP include path, the first thing I needed to do to create a Wordpress Plugin was to enable my plugin to call the Zend Framework classes. First I tried this towards the end of my wp-config.php file:

require_once 'Zend/Loader.php'; 
function __autoload($class) 
{ 
  Zend_Loader::loadClass($class); 
} 


This caused Wordpress to freak out like a chihuahua on speed. Not good. I figured we'd have to do something special because we don't want ALL the classes to autoload, just the Zend ones. So I scrapped my previous __autoload and tried this instead:

require_once 'Zend/Loader.php'; 
function __autoload($class) 
{ 
  $pos = strpos($class, 'Zend'); 
  if ($pos !== false) 
  { 
    Zend_Loader::loadClass($class); 
  } 
} 

Ahh, success. Sweeter then a brownie sundae with extra chocolate sauce.

From there, the rest is easy. Here's some basic code for the rz_delicious plugin, a basic PHP file you can drop into your Wordpress Plugins dir. It uses Zend_Cache and Zend_Service_Delicious to put your del.icio.us bookmarks onto your Wordpress blog. It first checks to see if there's a cached version already, if not, it uses the del.icio.us API to fetch your latest bookmarks. It does some list formatting there too because I didn't feel like handling that in my theme.

< ?php 
/* 
Plugin Name: RZ Delicious 
Plugin URI: http://www.boringuys.com/ 
Description: YADelicious Plugin 
Author: Rich Zygler 
Version: 1.0 
Author URI: http://www.boringguys.com/ 
*/ 

/* 
called from theme via: 
get_rz_delicious() 
*/ 

function get_rz_delicious() 
{ 
  $output = ''; 
  $username = 'username'; 
  $password = 'password'; 
  $tag      = 'tagname'; 
  $numPosts      = 15; 
  $cacheTime     = 3600;      // seconds 
  $cacheDir      = '/tmp/'; 

$frontendOptions = array( 
  'lifetime' => $cacheTime,                  // in seconds 
  'automatic_serialization' => false  // this is default anyway 
); 

$backendOptions = array('cache_dir' => $cacheDir); 

$cache = Zend_Cache::factory('Output', 'File', $frontendOptions, $backendOptions); 

// we pass a unique identifier to the start() method 
if(!$cache->start('rz_delicious')) 
{ 
  try 
  { 
    $delicious = new Zend_Service_Delicious($username, $password); 
    $posts = $delicious->getRecentPosts($tag,$numPosts);  //$tag 

    if (count($posts) > 0) 
    { 
      $output .= '
    '; } foreach ($posts as $post) { $output .= '
  • ';
    $output .= $post->getTitle() . '
    ';

    $strTags = ' ( tags: ';
    foreach ($post->getTags() as $tag)
    {
    if ($tag != 'boringguys.com')
    {
    $strTags .= '';
    $strTags .= $tag . '
    | ';
    }
    }
    $strTags = trim($strTags, '| ');
    $output .= $strTags . ' ) ';
    }
    if (count($posts) > 0)
    {
    $output .= '
'; } } catch (Zend_Service_Delicious_Exception $e) { // largely ignore the delicious service error $output .= '
    '; $output .= '
  • del.icio.us service unavailable
  • '; $output .= ''; } echo $output; $cache->end(); // the output is saved and sent to the browser } }
read more...

8.16.2006

Handy AJAX data structures using JSON, XML, ADODB, PHP, and Mysql

I'm working on a project where I thought a little AJAX magic would help the user interface a bit, so I've been adding that functionality piece by piece. For this web site, we've previously standardized on using the ADODB PHP database abstraction library for all our queries.

The particular circumstances of the XMLHttpRequest callbacks usually required a few small rows of data to be returned. So, the challenge became how to use the ADODB record sets to create structures that were nice and portable for use with AJAX. Most of the examples of JSON code shows only the properties of one object being displayed. But to return multiple rows, you basically need an object with an object (ie, rows within a dataset)
There's currently quite a debate raging on whether to return XML or JSON for manipulating via JavaScript. I use both approaches depending on the situation but find that I prefer JSON the most. Here are functions for ADODB that will return both XML and JSON as well as examples of usage. These files can be copied from below or downloaded at:

http://www.boringguys.com/example_code/adodb/toxml.inc.txt
http://www.borignguys.com/example_code/adodb/tojson.inc.txt

Just remember to rename them to .php !!

Here's that same code:

toxml.inc.php
/** 
* Creates XML from the ADODB record set 
* 
* @param     object         $rs         - record set object 
* @param     bool        $moveFirst    - determines whether recordset is returned to first record 
* @return     string        $xml        - resulting xml 
* @version V1.0  10 June 2006  (c) 2006 Rich Zygler ( http://www.boringguys.com/ ). All rights reserved. 
* 
*    Released under both BSD license and Lesser GPL library license. You can choose which license 
*    you prefer. 
*/ 

function rs2xml($rs, $moveFirst = false) 
{ 
  if (!$rs) 
  { 
    printf(ADODB_BAD_RS,'rs2xml'); 
    return false; 
  } 

  $xml = ''; 
  $totalRows = 0; 
  $totalRows = $rs->numrows(); 

  $domxml = new DOMDocument('1.0', 'utf-8'); 
  $root = $domxml->appendChild($domxml->createElement('rows')); 
  $root->setAttribute('total-rows', $totalRows); 

  $row_count = 1; 
  while($line = $rs->fetchRow()) 
  { 
    $row = $root->appendChild($domxml->createElement('row')); 

    foreach ($line as $col_key => $col_val) 
    { 
      $col = $row->appendChild($domxml->createElement('column')); 
      $col->setAttribute('name', strtolower($col_key)); 
      $col->appendChild($domxml->createTextNode($col_val)); 
    } 
    $row_count++; 
  } 
  $domxml->formatOutput = true; 
  $xml = $domxml->saveXML(); 
  $domxml = null; 

  if ($moveFirst) 
  { 
    $rs->MoveFirst(); 
  } 
  return $xml; 
} 


tojson.inc.php
/** 
* Creates JSON ( http://www.json.org/ ) from the ADODB record set 
* 
* @param     object         $rs         - record set object 
* @param     bool        $moveFirst    - determines whether recordset is returned to first record 
* @return     string        $output        - resulting json string 
* @version V1.0  10 June 2006  (c) 2006 Rich Zygler ( http://www.boringguys.com/ ). All rights reserved. 
* 
*    Released under both BSD license and Lesser GPL library license. You can choose which license 
*    you prefer. 

Example output from query  "SELECT Name, Continent From Country LIMIT 10;" 

{"rows":[ 
{"row":{"Name":"Afghanistan","Continent":"Asia"}}, 
{"row":{"Name":"Netherlands","Continent":"Europe"}}, 
{"row":{"Name":"Netherlands Antilles","Continent":"North America"}}, 
{"row":{"Name":"Albania","Continent":"Europe"}}, 
{"row":{"Name":"Algeria","Continent":"Africa"}}, 
{"row":{"Name":"American Samoa","Continent":"Oceania"}}, 
{"row":{"Name":"Andorra","Continent":"Europe"}}, 
{"row":{"Name":"Angola","Continent":"Africa"}}, 
{"row":{"Name":"Anguilla","Continent":"North America"}}, 
{"row":{"Name":"Antigua and Barbuda","Continent":"North America"}} 
]} 

*/ 

function rs2json($rs, $moveFirst = false) 
{ 
  if (!$rs) 
  { 
    printf(ADODB_BAD_RS,'rs2json'); 
    return false; 
  } 

  $output = ''; 
  $rowOutput = ''; 

  $output .= '{"rows":'; 
  $totalRows = $rs->numrows(); 

  if($totalRows > 0) 
  { 
    $output .= '['; 
    $rowCounter = 1; 
    while ($row = $rs->fetchRow()) 
    { 
      $rowOutput .= '{"row":{'; 
      $cols = count($row); 
      $colCounter = 1; 
      
      foreach ($row as $key => $val) 
      { 
        $rowOutput .= '"' . $key . '":'; 
        $rowOutput .= '"' . $val . '"'; 

        if ($colCounter != $cols) 
        { 
          $rowOutput .= ','; 
        } 
        $colCounter++; 
      } 

      $rowOutput .= '}}'; 

      if ($rowCounter != $totalRows) 
      { 
        $rowOutput .= ','; 
      } 
      $rowCounter++; 
    } 
    $output .= $rowOutput . ']'; 
  } 
  else 
  { 
    $output .= '"row"'; 
  } 

  $output .= '}'; 

  if ($moveFirst) 
  { 
    $rs->MoveFirst(); 
  } 
  return $output; 
} 


Example Usage

Place both of the files into your existing ADODB directory. If you don't already have the "world" sample database from mysql set up, please go and get it and install it ( http://dev.mysql.com/doc/ ). Make sure that the toxml and tojson files from above are placed in your adodb/ dir. Then use the following sample pages. Make sure to change your db settings in the file to what's appropriate. You will need PHP5 for the XML example. But you could easily mock up a version of that in PHP4, or you could always use this.

To test it out just do something like this for xml


or this for json

read more...

8.02.2006

How to get a C# class to talk to Mysql in under 5 minutes

I had to access a Mysql database at work today using C# and .NET. Well, I didn't have to... but I wanted to... and I had some down time. I'm mainly a PHP guy, but C# is similar enough to C/C++ that I figured out what I needed to do in a few minutes. I think it's always important to step out of your safe little world every now and again to try something radically different. It keeps your problem solving skills fresh.

Here's the rundown for those interested.
  • Download Mysql Connector/Net package http://dev.mysql.com/downloads/connector/net/1.0.html
  • While you're there, if you don't have the Mysql sample db "world" set up on your server, you should get that too at http://dev.mysql.com/doc/ (I'm assuming you know how to set this upin Mysql.
  • Install it on the Windows server you are using (and on your dev machine too)
  • Open up Visual Studio (2k5 if you got it)
  • Open up yer C# project
  • In the References of your project, Add a reference to the Mysql Connector. You'll probably need to go to the "browse" tab and go find it. The default install puts a Mysql.Data.dll in C:\Program Files\MySQL\MySQL Connector Net 1.0.7\bin\.NET 2.0
  • For my sample below, you'll also need to add the System and System.Data .NET references
  • Then plop this test code into a C# project. This example is just a stand-alone console app to get you going. There's plenty of documentation at http://www.mysql.org/doc/refman/4.1/en/connector-net.html to keep you motivated.
using MySql.Data.MySqlClient; 

class mysql 
{ 
  static void Main() 
  { 
    MySqlConnection conn; 
    string myConnectionString; 

    myConnectionString = "server=localhost;user id=test; pwd=test;database=world;"; 

    try 
    { 
      conn = new MySqlConnection(); 
      conn.ConnectionString = myConnectionString; 
      conn.Open(); 

      string sql = "SELECT Name, Continent FROM Country Limit 10"; 

      MySqlCommand cmd = new MySqlCommand(); 
      MySqlDataReader results; 
      cmd.CommandText = sql; 
      cmd.Connection = conn; 
      results = cmd.ExecuteReader(); 

      while (results.Read()) 
      { 
        //string f1 = results.GetString(0); 
        //int f2 = results.GetInt32(1); 
        System.Console.WriteLine(results.GetString(0) + ", " + results.GetString(1)); 
      } 

      results.Close(); 
      System.Console.ReadLine(); 
    } 
    catch (MySqlException ex) 
    { 
      System.Console.WriteLine("error" + ex.Message); 
      System.Console.ReadLine(); 
    } 
  } 
}

read more...

7.17.2006

Functionality of the PHP trim command I bet you did not know

trim

(PHP 3, PHP 4 , PHP 5)trim -- Strip whitespace from the beginning and end of a string

Description

string trim ( string str [, string charlist]) You can also specify the characters you want to strip, by means of the charlist parameter. Simply list all characters that you want to be stripped. With .. you can specify a range of characters. Example:

$strComma = "item 1, item 2, item 3,"; 
echo trim($strComma, ',');
read more...

7.06.2006

Everybody else is doing the Ajax Whois, why not me?

A buddy at work fell in love with the Ajax Whois and wanted a version on his own linux site. I've been playing around with a lot of Ajax stuff lately so I thought I'd give it a go using Ajax (javascript) and PHP. Here's the resulting code. It's just a quick and dirty solution because I had some technical difficulties working on his crappy server. I couldn't upload anything (like the brilliant prototype js library) so I had to bake most of the js from scratch except for a line borrowed here and there, most notably from this guy. Of course the other informal rule was that it had to be completed during spare time at work today. It's just two files, index.php and whois.php (rename the saved files with .php extension). Download and enjoy your own web based ajax whois. Just be careful not to get yourself blacklisted by doing tons of searches in a short time period.
read more...

11.18.2005

Configuration variables via Singleton object in PHP4

There is probably no design pattern handier and easier to set up than a Singleton pattern. One of the best uses in PHP apps is for configuration variables. You can use define all over the place or you can use $GLOBAL but things work a lot better when you have nice neat place to set and get global configuration variables. Enter the Singleton Configuration object. Here's some simple code for the object itself, simply named Config.php:

/** 
* Web Config object using Singleton pattern 
* 
* @author Rich Zygler, Jr. 
* @datecreated 03/08/2005 
* @access public 
* @usage $config =& Config::getInstance(); 
* @usage $config->setConfig('admin_email', 'test@test.com'); 
* @usage $email = $config->getConfig('admin_email'); 
* @TODO 
*/ 

class Config 
{ 
  var $configVars = array(); 

/* 
* Create a new config object 
*/ 
  function &getInstance() 
  { 
    static $instance; 
    if (!$instance) 
    { 
      $instance = array(new Config); 
    } 
    return $instance[0]; 
  } 

/* 
* Get config data 
* 
* @param     $key string - array key of variable whose data we are retrieving 
* @return    $this->configVars string 
*/ 
  function getConfig($key) 
  { 
    return $this->configVars[$key]; 
  } 

/* 
* Set config data 
* 
* @param     $key string -variable to retrieve data stored 
* @param     $value string -variable that contains data to store 
* @return    true 
* Can use arrays as well as in  $config->setConfig('email_list', array(//... )); 
* retrieve array by foreach($config->getConfig('email_list') as $email) { //... } 
* 
*/ 

  function setConfig($key, $val) 
  { 
    $this->configVars[$key] = $val; 
    return true; 
  } 

} 


If you think the getInstance method looks a little borked, you're right. What we're doing there is attempting to return the first and only the first implementation of this object. So everytime you make a call to this config object, you should be getting the same one. That's why we return the [0]th item in the array. This is a little easier in PHP5 but for PHP4, this is what we're stuck with.

And here's how to use this bad boy:

/** 
* config include 
* 
* @author Rich Zygler, Jr. 
* @datecreated 03/08/2005 
* @TODO 
*/ 

// Bring in the Config class file 
require_once ('Config.php'); 

// Instantiate our config object 
// Remember in PHP4, we use the  =& 
// to pass by reference 

$config =& Config::getInstance(); 

// Set up some config vars 
// will change per application 
// The usage here is:     setConfig(varName, varValue) 

$config->setConfig('appVersion', '1.o'); 
$config->setConfig('appName','Tester'); 
$config->setConfig('debug', true); 

// Maybe set the DB connection vars 
$config->setConfig('dbconn', array( 
  'username' => 'bunsen', 
  'password' => '!honeydew%', 
  'host'     => 'localhost', 
  'db'       => 'test', 
  'type'     => 'mysql' 
  ) 
); 

// Now to get those values back from the $config object 

// first let's initialize our vars 
$appVersion = ''; 
$appName = ''; 
$debug = false; 
$dbConnArray = array(); // used for getting back db values 
$dbUser = ''; 
$dbPass = ''; 
$dbHost = ''; 
$dbType = ''; 
$dbName = ''; 

// Now let's get the values from the config object and populate our variables 
// of course, for a fully functioning app, you may want to check that these values are set 
$appVersion = $config->getConfig('appVersion'); 
$appName = $config->getConfig('appName'); 
$debug = $config->getConfig('debug'); 

// Here, we slurp the whole array from the config into a new array 
$dbConnArray = $config->getConfig('dbconn'); 
$dbUser  = $dbConnArray['username']; 
$dbPass  = $dbConnArray['password']; 
$dbHost     = $dbConnArray['host']; 
$dbType     = $dbConnArray['type']; 
$dbName    = $dbConnArray['db']; 

// Now let's echo everything out to make sure the values are 
// coming back correctly 
echo "The version is: $appVersion"; 
echo "The name is: $appName"; 
echo "The debugger is on: $debug (1 = true) "; 
echo "The db username is: $dbUser "; 
echo "The db password is: $dbPass "; 


What's great about this method of doing things is that you virtually eliminate the need for global variables in functions and objects. This is a very good thing. If you need some configuration variables available to a function or object, you can pass it this config object like this:

// call the function this way 
doSomethingWithConfig($config); 

// define the function this way 
// Remember to accept the object by reference (add the &) 
// otherwise a copy of the config data is created -- not good 

function doSomethingWithConfig(&$config) 
{ 
  // get app version 
  $appVersion = ''; 
  $appVersion = $config->getConfig('appVersion'); 
  return $appVersion; 
}


If you like this way of doing things, wait until you try to recreate this in PHP5, it's even easier.
read more...

11.09.2005

The SqlXML class -- PHP sql query results in XML via object

For a personal project that I’m working on in PHP4, I’m using XSLT to display a bunch of pages. Most times, I don’t use the XSL transforms for the whole page, usually just tables of data that are returned from a query. The first thing that you need to do an XSL transform is a nice chunk of XML data. It would be pretty handy if when we queried the database, it returned our results as XML that we could use for the transform. More robust database systems like Oracle can do this right out of the box, but Mysql needs some help from PHP. I created a nice little object to take care of this for me.

The object does a few things. There are two methods in the object, query and queryPaged. The query method just does a straight query to the db and returns the results as XML. The queryPaged method also does a query to the db and returns the results as XML. But this method takes on a few extra parameters so that it can return page navigation information in the XML also. This way, you can set up paged data tables with navigation (page 1, page 2, etc.) instead of just glomming out hundreds of rows of data.

First things first – The query method


First off, we need to include our db connection stuff and our SqlXML object file. Then we can create our sql. Then instantiate the SqlXML object and pass it our sql. Here's that code:

// start db connection 
require_once('db.php'); // left to the reader to do 
require_once('SqlXML.php'); // full code to this program below 

$sql = "SELECT * FROM customers LIMIT 10"; 

$sqlxml =& new SqlXML(); 
$xml = $sqlxml->query($sql); 

Pretty simple right? If you want to see the results, you can always just echo out a textarea:

echo '';

Your results will obviously depend on your query, but an excerpt of mine look something like this:

<?xml version="1.0"?> 

  
    
      1
      Harry
      harry@test.com 
    
    
      2
      Tom
      tom@test.com 
    
 


So the method creates an XML “row” element for each row returned. Each field in the row returned gets its own “column” element. Each “column” element has a “name” attribute which tells you which field that data is for.

Keep in mind here that $xml is a string and not an xml object at this point. All the domxml stuff is handled inside the SqlXML object so we don’t have to fuss with it outside the object.

So how does this thing work? Well, first, it executes the query. If something didn’t work in the query, it just returns this as a string, not as XML.

function query($query) 
{ 
  $xml = ''; 
  $result = mysql_query($query); 
  if (!$result) 
  { 
    return 'Query failed: ' . mysql_error(); 
  }

Then it records the number of rows in the data.

$totalRows = mysql_num_rows($result);

The method then starts to build the xml tree by setting a result-set element at the root with an attribute of total-rows. The method then goes on to build the rest of the xml tree, row by row. I should note here that you do need the domxml extensions for PHP installed. All the XML creation in the object is done with domxml methods, no lame XML-as-string solutions here. Here’s the code snip of that area of the code:

$rowCount = 1; 
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
{ 
  $row = $root->append_child($dom->create_element("row")); 
  $row->set_attribute("number", $rowCount); 

  foreach ($line as $colKey => $colValue) 
  { 
    $col = $row->append_child($dom->create_element("column")); 
    $col->set_attribute("name", strtoupper($colKey)); 
    $col->append_child($dom->create_text_node($colValue)); 
  } 
  $rowCount++; 
} 

Here, the while loop creates the row elements in our resulting xml and the foreach loop creates the column elements.

Once you have your xml in that $xml variable, you can bring it in to your XSL transform (article coming soon...). Here is the full code for using the query method of the object.

// start db connection 
require_once('db.php'); // left to the reader to do 
require_once('SqlXML.php'); // full code to this program below 

$sql = "SELECT * FROM customers LIMIT 10"; 

$sqlxml =& new SqlXML(); 
$xml = $sqlxml->query($sql); 
echo ''; 

// then take that $xml string and transform with the appropriate XSL 

Now what if you wind up with a lot of data from your query? For me, if I'm displaying any more than about 20 rows of data, I'm going to paginate it (place 20 rows on each page with some page to page naviation). We can use the queryPaged method of the SqlXML object for this. But I'll save that for another article.

Here's the complete SqlXML.php class.

class SqlXML 
{ 
  var $resultsPerPage = 0; 
  var $curPage = 0; 
  var $sort_by; 
  var $sort_dir; 

  function SqlXML() 
  { 

  } 

  function query($query) 
  { 
    $xml = ''; 
    $result = mysql_query($query); 
    if (!$result) 
    { 
      return 'Query failed: ' . mysql_error(); 
    }
 
    $totalRows = mysql_num_rows($result); 
    $dom = domxml_new_doc("1.0"); 
    
    $root = $dom->append_child($dom->create_element('result-set')); 
    $root->set_attribute('total-rows',$totalRows); 

    $rowCount = 1; 
    while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
    { 
      $row = $root->append_child($dom->create_element("row")); 
      $row->set_attribute("number", $rowCount); 

      foreach ($line as $colKey => $colValue) 
      { 
        $col = $row->append_child($dom->create_element("column")); 
        $col->set_attribute("name", strtoupper($colKey)); 
        $col->append_child($dom->create_text_node($colValue)); 
      } 
      $rowCount++; 
    } 

    $xml = $dom->dump_mem(); 

    // Free resultset 
    mysql_free_result($result); 
    return $xml; 
  } 

  function queryPaged($queryFields, $queryTail, $scriptPath = '') 
  { 
    $recCount = 0; 
    $totalPages = 0; 
    $xml = ''; 

    // get the total count without getting field data 
    $queryCt = "SELECT COUNT(*) " . $queryTail; 
    $resultCt = mysql_query($queryCt); 

    if (!$resultCt) 
    { 
      return 'Query failed: ' . mysql_error(); 
    } 

    // calc total pages 
    $row = mysql_fetch_row($resultCt); 
    $recCount = $row[0]; 

    if ($recCount > 0) 
    { 
      $query = "SELECT " . $queryFields . $queryTail; 
      if ($this->resultsPerPage != 0) 
      { 
        $recStart = ($this->curPage * $this->resultsPerPage) - $this->resultsPerPage; 

        // add limit to query 
        $query .= " LIMIT $recStart, $this->resultsPerPage"; 
      } 

      mysql_free_result($resultCt); 
      $result = mysql_query($query); 

      if (!$result) 
      { 
        return 'Query failed: ' . mysql_error(); 
      } 

      // calc total pages 
      $recCount2 = mysql_num_rows($result); 
      if (!$recCount2) 
      { 
        return 'Query failed : ' . mysql_error(); 
      } 

      $totalPages = floor($recCount / $this->resultsPerPage); 
      if ($recCount % $this->resultsPerPage > 0 ) 
      { 
        $totalPages++; 
      } 
    } 

    // create xml 
    $dom = domxml_new_doc("1.0"); 
    $rs = $dom->append_child($dom->create_element('result-set')); 
    $rs->set_attribute('total-rows',$recCount); 
    $rs->set_attribute('results-per-page', $this->resultsPerPage); 
    $rs->set_attribute('total-pages', $totalPages); 
    $rs->set_attribute('current-page', $this->curPage); 
    $rs->set_attribute('script-path', $scriptPath); 

    if (isset($this->sort_by) && isset($this->sort_dir) && $this->sort_by != '' && $this->sort_dir != '') 
    { 
      $rs->set_attribute('sort-by', $this->sort_by); 
      $rs->set_attribute('sort-dir', $this->sort_dir); 
    } 

    $nav = $rs->append_child($dom->create_element('nav')); 

    // create XML to set up paging 
    for ($i = 1; $i < = $totalPages; $i++) 
    { 
      $page = $nav->append_child($dom->create_element('page')); 
      $page->set_attribute('num', $i); 
      if ($i == $this->curPage) 
      { 
        $page->set_attribute('current-page', 'true'); 
      } 
    } 

    $rows = $rs->append_child($dom->create_element('rows')); 

    if ($recCount > 0) 
    { 
      $rowCount = 1; 
      while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
      { 
        $row = $rows->append_child($dom->create_element("row")); 
        $row->set_attribute("number", $rowCount); 

        foreach ($line as $colKey => $colValue) 
        { 
          $col = $row->append_child($dom->create_element("column")); 
          $col->set_attribute("name", strtoupper($colKey)); 
          $col->append_child($dom->create_text_node($colValue)); 
        } 
        $rowCount++; 
      } 
    } 

    if (is_resource($result)) 
    { 
      mysql_free_result($result); 
    } 
    $xml = $dom->dump_mem(); 

    return $xml; 
  } 
} 

read more...