Read RSS Reed
search...

XAJAX Autocompleter V2

September 11th, 2009

rarecore autocompleterIt is often helpful to use an autocompleter on your website. Perhaps in search dialogs? An example is google on an extra search page.

I tested some free tools, but I had always the problem that there was no possibility to use two or more autocompleter on one page and to organize the dependency. E.g. insert a name of a country in the first textbox and in the second textbox insert a name of a city. On the city textbox you only want to see cities belonging to the inserted country – no other cities.

This problem was the reason why I developed my own autocompleter using xajax. This framework allows me to respond on the key events and select the values from the database. I could write my own functions and use any parameters.

I generated a textbox with a hidden div below which is calling a function on the onkeyup event by using xajax. In this test I mark the searched string with a span and on CSS I colored it blue. Additional I added a mouseover using CSS.

Here you could download the second version of my autocompleter.

Changes:
– Using the arrow keys to choose the correct value
– Performance Tuning

Demo
http://blog.rarecore.eu/wp-content/plugins/downloads-manager/img/icons/default.gif download: Autocompleter v2 (119.55KB)
added: 08/11/2009
clicks: 2553

PHP 5 memcache extension on Debian Etch as session handler

May 13th, 2009

Have you ever thought about a method of saving sessions without getting a lot of session files or using a selfmade session handler?
The answer for this question is memcache. A module giving you the ability to store variables in memory for a defined time. You can install the module on a Linux and a Windows Server. I only want to explain you how to set it up on Linux Debian Etch.

At first you have to do is to install the server module.

apt-get install memcached

If the application is already started, we have to kill the process to setup what we want.

memcached -d -u www-data -m 2048 -l 127.0.0.1 -p 11211

Explain this command:
memcached (command)
-d (the parameter to run it in background)
-u www-data (to run it under the standard apache2 user www-data)
-m (Sets the space of the memcached server (in Mega Byte) (in this example 2048 MB (Mega Byte))
-l (Sets the IP the memcached server listens to)
-p (Sets the Port the memcached server listens to)

Now the memcache server runs as www-data with a space of 2024 MB RAM which is listen to localhost:11211. The next step is to involve PHP. For that we have to enable the module memcache.

You could get the latest version here. Please use the wget command to download the file. (Note: replace X.X.X. with the current version)

cd /usr/local/src
wget http://pecl.php.net/get/memcache-X.X.X.tgz
tar zxvf memcache-X.X.X.tgz
cd memcache-X.X.X
apt-get install php5-dev
phpize
./configure
make && make install

Okay we have compiled the files. Now you have to move the memcache.so to your extension folder of PHP5. In my case I found the memcache.so in /usr/local/lib/php/extensions/no-debug-non-zts-20060613/memcache.so, but maybe your location is different.

Now copy the file to /usr/lib/php5/20060613+lfs

The next step is to get the latest version of the memcache php5 extension in our extension directory. All we have to do now is to configure the php.ini by adding the following line.

extension=memcache.so

Before you could restart the apache2 server you need to set up the memcache that it will be used as session handler. The standard will look like this:

session.save_handler = files
session.save_path = "N;MODE;/path"
session.gc_probability = 0

You have to change it to:

session.save_handler = memcache
session.save_path="tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
session.gc_probability = 1

Save the ini file and restart your apache2 server.

/etc/init.d/apache2 restart

When you take now a look into your phpinfo it should look like this:

(the white spaces are private settings)
Congratulations! If you create now a session it will be stored into the memory instead of creating a file.

Fiddler2 – The Web Debugging Proxy

April 8th, 2009

A friend told me something about a tool called fiddler2. It is a web debugging proxy. You only have to start this program and surf in the internet. You can see which pages / files are opened by each application, you can check the status (HTTP Status) and the used protocol, too.

It helps a lot by searching for errors!

News updated

March 12th, 2009

It is just a small update for us, but a big for SEO.

Now on the We aRe oNe Pages the news have a new link and the page title changed, too. For exampe the new release of Phunkless is linked on http://www.technobase.fm/news/9029-phunkless-i-wont-let-you-down.

Enjoy it!

Autocompleter using XAJAX

February 6th, 2009

rarecore autocompleter It is often helpful to use an autocompleter on your website. Perhaps in search dialogs? An example is google on an extra search page.

I tested some free tools, but I had always the problem that there was no possibility to use two or more autocompleter on one page and to organize the dependency. E.g. insert a name of a country in the first textbox and in the second textbox insert a name of a city. On the city textbox you only want to see cities belonging to the inserted country – no other cities.

This problem was the reason why I developed my own autocompleter using xajax. This framework allows me to respond on the key events and select the values from the database. I could write my own functions and use any parameters.

I generated a textbox with a hidden div below which is calling a function on the onkeyup event by using xajax. In this test I mark the searched string with a span and on CSS I colored it blue. Additional I added a mouseover using CSS.

Demo *** NEW VERSION ***

http://blog.rarecore.eu/wp-content/plugins/downloads-manager/img/icons/default.gif download: Autocompleter v2 (119.55KB)
added: 08/11/2009
clicks: 2553

That’s all!

Blog Ping Server List *Update*

January 28th, 2009

I’ve found a blog ping server list.
Now, we are pinging:

*Update*
Thx to Ak.Tronic (see comments)

http://blogsearch.google.com/ping/RPC2
http://1470.net/api/ping
http://api.feedster.com/ping
http://api.feedster.com/ping.php
http://api.moreover.com/ping
http://api.moreover.com/RPC2
http://api.my.yahoo.com/RPC2
http://api.my.yahoo.com/rss/ping
http://bblog.com/ping.php
http://bitacoras.net/ping
http://blogdb.jp/xmlrpc
http://blog.goo.ne.jp/XMLRPC
http://blogmatcher.com/u.php
http://bulkfeeds.net/rpc
http://coreblog.org/ping/
http://mod-pubsub.org/kn_apps/blogchatt
https://phobos.apple.com/WebObjects/MZFinance.woa/wa/pingPodcast
http://ping.amagle.com/
http://ping.bitacoras.com
http://ping.bloggers.jp/rpc/
http://ping.blogmura.jp/rpc/
http://ping.blo.gs/
http://ping.cocolog-nifty.com/xmlrpc
http://pinger.blogflux.com/rpc/
http://ping.exblog.jp/xmlrpc
http://ping.feedburner.com
http://ping.myblog.jp
http://pingoat.com/goat/RPC2
http://pingqueue.com/rpc/
http://ping.blogg.de/
http://ping.rootblog.com/rpc.php
http://ping.syndic8.com/xmlrpc.php
http://ping.weblogalot.com/rpc.php
http://ping.weblogs.se/
http://rcs.datashed.net/RPC2/
http://rpc.blogbuzzmachine.com/RPC2
http://rpc.blogrolling.com/pinger/
http://rpc.britblog.com/
http://rpc.icerocket.com:10080/
http://rpc.newsgator.com/
http://rpc.pingomatic.com/
http://rpc.tailrank.com/feedburner/RPC2
http://rpc.technorati.com/rpc/ping
http://rpc.weblogs.com/RPC2
http://rpc.wpkeys.com/
http://services.newsgator.com/ngws/xmlrpcping.aspx
http://signup.alerts.msn.com/alerts-PREP/submitPingExtended.doz
http://topicexchange.com/RPC2
http://trackback.bakeinu.jp/bakeping.php
http://www.a2b.cc/setloc/bp.a2b
http://www.bitacoles.net/ping.php
http://www.blogdigger.com/RPC2
http://www.blogoole.com/ping/
http://www.blogoon.net/ping/
http://www.blogpeople.net/servlet/weblogUpdates
http://www.blogroots.com/tb_populi.blog?id=1
http://www.blogshares.com/rpc.php
http://www.blogsnow.com/ping
http://www.blogstreet.com/xrbin/xmlrpc.cgi
http://www.lasermemory.com/lsrpc/
http://www.imblogs.net/ping/
http://www.mod-pubsub.org/kn_apps/blogchatter/ping.php
http://www.newsisfree.com/RPCCloud
http://www.newsisfree.com/xmlrpctest.php
http://www.popdex.com/addsite.php
http://www.rssfwd.com/xmlrpc/api
http://www.snipsnap.org/RPC2
http://www.weblogues.com/RPC/
http://xmlrpc.blogg.de
http://xping.pubsub.com/ping/
http://www.wasalive.com/ping/
http://blogping.unidatum.com/RPC2/
http://ping.wordblog.de/

Does anybody know other ping server?

The unsupported TinyMCE BB Code Bug…

December 5th, 2008

TinyMCE is a nice WYSIWYG Editor for a Webapplication. In my application I’m very interested in allowing the users to use BB Code to optimize the visualisation of the texts (guestbooks, news comments, …). Before I released the TinyMCE Editor on my Webradio website, I did some tests.

1. At first, I entered the following text into my textarea:

2. After submit the form, I get this text displayed:

Now you can see that the text which is between the <strong> tag is now displayed as bold. But, it shouldn’t be! If I choose the BB code plugin I think the html tag should be disabled…

3. After submit the form again, I get this text displayed:

Well, now my HTML Tag is rendered as a bb code tag. That’s wrong. I want to display the html tag and not a formatted bb code text.

I searched for support, but nobody on the TinyMCE board helps me…
After some tests, I think, I fixed the bug.

Please change the _tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin.js file and add the following lines to line 47 (before replacing the old tags).

rep(/&amp;lt;/gi,"&amp;amp;lt;");
rep(/&amp;gt;/gi,"&amp;amp;gt;");

Download bugfix

NFS, the slow performance Network File System

September 29th, 2008

As described, we are using 2 web servers and 1 application server. What’s the background? It’s easy to explain. Every good designed and developed website needs a template engine for visualization. Our template engine is smarty. Smarty has the caching feature and I like it to minimize the database connections and optimize the performance. I cache some pages (profile, news) until the next update (e.g. new comment) was done.

The problem is if the PHP script has deleted the cache file on the first web server (tbweb01), the cache file on the second web server (tbweb02) isn’t deleted. To avoid any delay times, we stored our source code on the application server and we are using NFS to share the files. Normally it works fine, but on some peak times the NFS is too slow.

Information like “logged in user” and so on are saved on the session. Usually the user opens the website and the browser always uses the same ip address. It does not matter which server it is. If the user uses a proxy, the proxy chooses one of the round robin ip addresses by each click. So on one server the user has a correct session with the information, on the other server he hasn’t. If we store the sessions on the NFS we make sure that every server uses the same session. But the performance…

Now we have to search for a good solution!
I found two interesting articles. One about a session_set_save_handler and the other about a cache_handler_func. And a new idea was born. Use NFS only to read the files and store the information in the database.

session_set_save_handler:
This default PHP function allows you to use your own way for the session handling. I think it’s really better to store everything in a mysql table and avoid the NFS storage. On the article they didn’t open and close a database connection. That’s bad… Normally your page is already using a connection, but sometimes you don’t have to open one.

It’s a little bit tricky, but not a problem for experienced developer. I wrote a class to handle my database connection(s). It was very important to use one class for more connections, but it was much more important that the class doesn’t connect with the same user and the same selected database twice times and make sure that the class closes every connection correct. I called my class “classDataBase” and overloaded the most used mysql functions. To make sure that the handling works, we’ve to use a static array for the connection and remember the used index in an attribute. Also we remember the count of objects for each connection. On calling the close function, we don’t want to close always the database connection. If more than one object uses this connection, we only decrease the count variable. To be sure that the PHP script closes all opened connections correctly, the class registers automatically on the initializing of the first object a static DBCloseAll() function for shutdown.

classDataBase.php

/******************************************
 * class created by Exi (http://www.technobase.fm/member/1)
 * please find some information about on
 * http://blog.rarecore.eu/nfs-the-unperformed-file-system.html
 ******************************************/
 
class classDataBase {
 
    public static $connections;
    var $connection;
    var $Idx = 0;
    var $DBName;
 
    // error handling
    var $errNum; // error number
    var $errTxt; // error message
 
    // constructor - set default values
    function classDataBase() {
        if(!is_array(classDataBase::$connections)) {
            classDataBase::$connections = array();
            register_shutdown_function(array('classDataBase', 'DBCloseAll'));
        }
 
        $this-&gt;errNum = 0;
        $this-&gt;errTxt = "";
        $this-&gt;connectionID = false;
    }
 
    function Init($cDBName, $cDBHost, $cDBUser, $cDBPass) {
        $found = false;
        $retVal = false;
 
        if($this-&gt;connection) {
            $this-&gt;DBClose();
        }
 
        for($i=0; $iconnection = $a['connection'];
                        classDataBase::$connections[$i]['count']++;
                        $this-&gt;Idx = $i;
                        $found = true;
                        $retVal = true;
                        break;
                    }
            }
        }
 
        if(!$found) {
            $a = array();
 
            $retVal = $this-&gt;DBConnecting($cDBName, $cDBHost, $cDBUser, $cDBPass);
 
            if(!$retVal) {
                //Lost connection to MySQL server at 'reading authorization packet', system error: 0
                if($this-&gt;errNum != 2013) {
                    $mail  = "Error on connect to the Databasen";
                    $mail .= "Error Text: ".$this-&gt;errTxt."n";
                    $mail .= "Error Number: ".$this-&gt;errNum."n";
 
                    $this-&gt;ErrorMail($mail);
                }
 
                echo "<strong>Error on connect to the Database</strong>";
                exit();
            }    
 
            $a['dbname'] = $cDBName;
            $a['dbhost'] = $cDBHost;
            $a['dbuser'] = $cDBUser;
            $a['connection'] = $this-&gt;connection;
            $a['count'] = 1;
            array_push(classDataBase::$connections, $a);
        }
 
        $this-&gt;DBName = $cDBName;
 
        return $retVal;
    }
 
    function DBConnecting($cDBName, $cDBHost, $cDBUser, $cDBPass) {
        $retVal = true;
 
        // connect to database
        $this-&gt;connection = @mysql_connect($cDBHost, $cDBUser, $cDBPass);
 
        // throw error if connection failed ...
        if (!$this-&gt;connection) {
            $this-&gt;errNum = @mysql_errno();
            $this-&gt;errTxt = @mysql_error();
            $retVal = false;
        } else if(!@mysql_select_db($cDBName, $this-&gt;connection)) {
            $this-&gt;errNum = @mysql_errno();
            $this-&gt;errTxt = @mysql_error();
            $retVal = false;
        }
 
        return $retVal;
    }
 
    //function to execute statements
    function execSQL($SQLQuery, $mail = true) {
        $XSQL = false;
 
        if($this-&gt;connection) {
            $XSQL = mysql_query($SQLQuery, $this-&gt;connection);
 
            // Check for error
            if (!$XSQL) {
                $this-&gt;errNum = @mysql_errno($this-&gt;connection);
                $this-&gt;errTxt = @mysql_error($this-&gt;connection);   
 
                if($mail) {
                    $this-&gt;LogDBError($SQLQuery);
                }
            }
        }
 
        return $XSQL;
    }
 
    function query($SQLQuery) {
        return $this-&gt;execSQL($SQLQuery);
    }
 
    function queryCatch($SQLQuery) {
        return $this-&gt;execSQL($SQLQuery, false);
    }
 
    function insertId() {
        return mysql_insert_id($this-&gt;connection);
    }
 
    function affectedRows() {
        return mysql_affected_rows($this-&gt;connection);
    }
 
    //function to fetch the query
    function fetchArray($SQLQuery) {
        $XSQL = @mysql_fetch_array($SQLQuery);
 
        if(!$XSQL) {
            return false;
        } else {
            return $XSQL;
        }
    }
 
    function numRows($SQLQuery) {
        $XSQL = @mysql_num_rows($SQLQuery);
 
        if(!$XSQL) {
            return 0;
        } else {
            return $XSQL;
        }
    }
 
    //function to send a mail on error to the programer
    function ErrorMail($Content) {
        // send an email to the programmer?
        echo '<strong>change the ErrorMail function!!!</strong>'.$Content;
    }
 
    function LogDBError($Statement = "") {
        /*
        // log the database errors?!?
        $qry = 'INSERT INTO dberror
                        SET dberr_number = ''.$this-&gt;errNum.'',
                            dberr_text = ''.mysql_escape_string($this-&gt;errTxt).'',
                            dberr_statement = ''.mysql_escape_string($Statement).'',
                            dberr_site = ''.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'',
                            dberr_ip = ''.$_SERVER['REMOTE_ADDR'].'',
                            dberr_time = ''.time().'',
                            dberr_sent = 0';
 
        @mysql_db_query($this-&gt;DBName, $qry, $this-&gt;connection);*/
 
        echo nl2br('
              dberr_number = ''.$this-&gt;errNum.'',
              dberr_text = ''.$this-&gt;errTxt.'''
             );
 
        echo '<strong>change the LogDBError function!!!'</strong>.$Statement;
    }
 
    function ListTables() {
        $result = @mysql_list_tables($this-&gt;DBName, $this-&gt;connection);
 
        $table_names = array();
 
        for($x=0; $x &lt; $this-&gt;numRows($result); $x++) {
            $table_names[$x] = @mysql_tablename($result,$x);
        }
 
        return $table_names;
    }
 
    function DBClose() {
        if($this-&gt;connection) {
            if(classDataBase::$connections[$this-&gt;Idx]['count'] == 1) {
                @mysql_close($this-&gt;connection);
            }          
 
            classDataBase::$connections[$this-&gt;Idx]['count']--;
            $this-&gt;connection = false;
        }
    }
 
    function DBCloseAll() {
        if(class_exists('mysql_session_handler')) {
            session_write_close();
        }
 
        for($i=0; $i
 
After creating our database class we want to write our own session handling. At first we've to create a simple MySQL Table. I called my table cache_session. I want to prefix my example tables with cache_.
CREATE TABLE `cache_sessions` (
  `session_id` varchar(100) NOT NULL default '',
  `session_data` text NOT NULL,
  `session_expires` int(11) NOT NULL default '0',
  PRIMARY KEY  (`session_id`)
) TYPE=innodb;

What is my session handler class doing? It’s a static class to overwrite the session handling. On construct I get the maxfiletime from the php configuration, I register my methods to read, write and destroy the session and create a database connection.

On read / write the session, the class use MySQL to store the information.

mysql_session_handler.php

/******************************************
 * class created by Exi (http://www.technobase.fm/member/1)
 * please find some information about on
 * http://blog.rarecore.eu/nfs-the-unperformed-network-file-system
 ******************************************/
include_once 'classDataBase.php';
if(!class_exists('mysql_session_handler')) {
    class mysql_session_handler {
        static $life_time;
        static $mysql;
 
        // construct
        function mysql_session_handler() {
            // read the maxlifetime setting from PHP
            mysql_session_handler::$life_time = get_cfg_var('session.gc_maxlifetime');    
 
            // register this object as the session handler
            session_set_save_handler(
                array(&amp;$this, 'open'),
                array(&amp;$this, 'close'),
                array(&amp;$this, 'read'),
                array(&amp;$this, 'write'),
                array(&amp;$this, 'destroy'),
                array(&amp;$this, 'gc')
            );  
 
            if(mysql_session_handler::$mysql == null) {
                // create a new database connection or use the already opened
                mysql_session_handler::$mysql = new classDataBase();
                mysql_session_handler::$mysql-&gt;Init('db', 'ip', 'user', 'password');
            }
        }
 
        // open session -&gt; just to have. no action
        function open($save_path, $session_name) {
            global $sess_save_path;
            $sess_save_path = $save_path;
            return true;
        }
 
        // read session data
        function read($id) {
            $data = '';
 
            $qry = mysql_session_handler::$mysql-&gt;query("select session_data
                                                           from cache_sessions
                                                          where session_id = '".mysql_escape_string($id)."'
                                                            and session_expires &gt;= ".time());
 
            while($fetch = mysql_session_handler::$mysql-&gt;fetchArray($qry)) {
                $data = $fetch[0];
            }
 
            return $data;
        }
 
        // insert / update session information
        function write($id, $data) {
            mysql_session_handler::$mysql-&gt;query("replace into cache_sessions
                                                              (session_id,
                                                               session_data,
                                                               session_expires)
                                                       values ('".mysql_escape_string($id)."',
                                                               '".mysql_escape_string($data)."',
                                                                ".(time() + mysql_session_handler::$life_time).")");
 
            return true;
        }
 
        // destroy a session
        function destroy($id) {
            mysql_session_handler::$mysql-&gt;query("delete from cache_sessions where session_id = '".mysql_escape_string($id)."'");
            return true;
        }
 
        // clean old session
        function gc() {
            // do not clean by an page call, use a cronjob to delete all expired entries every minute!
            /*mysql_session_handler::$mysql-&gt;query('delete from cache_sessions where session_expires &lt; '.time());*/
 
            return true;
        }
 
        // close session
        function close() {
            return true;
        }
    }   
 
    $SessionHandler = new mysql_session_handler();
}

Now, I want to do some tests…

include 'mysql_session_handler.php';
session_start();
if(!isset($_SESSION['a'])) {
    $_SESSION['a'] = 1;
    echo 'session "a" not set!';
} elseif($_SESSION['a'] == 10) {
    session_destroy();
    echo 'session destroyed';
 
} else {
    $_SESSION['a']++;
    echo 'session "a" set!';
}


looks good – works!

The next step is to store the smarty cache in the database. I always write my own classes to overwrite existing open source projects. So I could implement features / settings and software updates doesn’t touch me… I created a classSmarty and opened a database connection using the classDataBase class.

classSmarty.php

/******************************************
 * class created by Exi (http://www.technobase.fm/member/1)
 * please find some information about on
 * http://blog.rarecore.eu/nfs-the-unperformed-file-system.html
 ******************************************/
 
include_once 'Smarty.class.php';
include_once 'classDataBase.php';
include_once 'mysql_cache_handler.php';
 
class classSmarty extends Smarty {
    var $mysql;
 
    function classSmarty() {
        parent::Smarty(); 
 
        $this-&gt;template_dir  = '_smarty/templates';
        $this-&gt;compile_dir   = '_smarty/templates_c';
        $this-&gt;cache_dir     = '_smarty/cache';
        $this-&gt;config_dir    = '_smarty/config';
 
        $this-&gt;compile_check = true;
        $this-&gt;debugging     = false;
        $this-&gt;caching       = true;
 
        $this-&gt;mysql = new classDataBase();
        $this-&gt;mysql-&gt;Init('db', 'host', 'user', 'pass');
        $this-&gt;cache_handler_func = 'mysql_cache_handler';
    }
}

As descripted in the smarty forum I created a function to handle the caching by mysql.

CREATE TABLE `cache_smarty` (
  `smarty_cacheId` varchar(32) NOT NULL,
  `smarty_template` varchar(255) NOT NULL,
  `smarty_group` varchar(255) NOT NULL,
  `smarty_content` mediumtext NOT NULL,
  `smarty_expire` int(11) NOT NULL,
  PRIMARY KEY  (`smarty_cacheId`),
  KEY `smarty_template` (`smarty_template`),
  KEY `smarty_expire` (`smarty_expire`)
) ENGINE=InnoDB ;

mysql_cache_handler.php

/******************************************
 * class created by Exi (http://www.technobase.fm/member/1)
 * please find some information about on
 * http://blog.rarecore.eu/nfs-the-unperformed-file-system.html
 ******************************************/
 
function mysql_cache_handler($action, &amp;$smarty_obj, &amp;$cache_content, $tpl_file = null, $cache_group = null, $compile_id = null, $exp_time = 0) {
    $db_table = 'cache_smarty';
 
    // create unique cache id
    $cache_id = md5($tpl_file.$cache_group.$compile_id); 
 
    switch ($action) {
        case 'read':
            // read cache from database
            $results = $smarty_obj-&gt;mysql-&gt;query("select smarty_content from $db_table where smarty_cacheId = '$cache_id' and smarty_expire &gt; ".time()); 
 
            if(!$results) {
                $smarty_obj-&gt;_trigger_error_msg('cache_handler: query failed.');
            } 
 
            $row = $smarty_obj-&gt;mysql-&gt;fetchArray($results);
            $cache_content = $row[0]; 
 
            $return = $results;
            break; 
 
        case 'write':
            // save cache to database
            $results = $smarty_obj-&gt;mysql-&gt;query("replace into $db_table (
                                                           smarty_cacheId,
                                                           smarty_template,
                                                           smarty_group,
                                                           smarty_content,
                                                           smarty_expire
                                                         ) values (
                                                           '$cache_id',
                                                           '$tpl_file',
                                                           '$cache_group',
                                                           '".addslashes($cache_content)."',
                                                           '".($exp_time == 0 ? time() + 3600 : $exp_time)."' )"); // no expire =&gt; expire next hour
 
            if(!$results) {
                $smarty_obj-&gt;_trigger_error_msg('cache_handler: query failed.');
            } 
 
            $return = $results;
            break; 
 
        case 'clear':
            // clear cache info
            if(empty($cache_group) &amp;&amp; empty($compile_id) &amp;&amp; empty($tpl_file)) {
                $results = $smarty_obj-&gt;mysql-&gt;query("delete from $db_table"); 
 
            } else {
                /*
                if(!$smarty_obj-&gt;mysql-&gt;query("delete from $db_table where smarty_expire &lt; ".time())) {
                    $smarty_obj-&gt;_trigger_error_msg('cache_handler: clear expired entries query failed.');
                }
                */
 
                if(strpos($cache_group, '|')) {
                   if(!empty($tpl_file)) {
                      $results = $smarty_obj-&gt;mysql-&gt;query("delete from $db_table where smarty_template = '$tpl_file' AND smarty_group LIKE '$cache_group%'"); 
 
                   } else {
                      $results = $smarty_obj-&gt;mysql-&gt;query("delete from $db_table where smarty_group LIKE '$cache_group%'"); 
 
                   }
                } else {
                   $results = $smarty_obj-&gt;mysql-&gt;query("delete from $db_table where smarty_cacheId = '$cache_id'"); 
 
                }
            } 
 
            if(!$results) {
                $smarty_obj-&gt;_trigger_error_msg('cache_handler: query failed.');
            } 
 
            $return = $results;
            break; 
 
        default:
            // error, unknown action
            $smarty_obj-&gt;_trigger_error_msg("cache_handler: unknown action "$action"");
            $return = false;
            break;
    } 
 
    return $return;
}

Now, I want to do some tests again…

include_once 'classSmarty.php';
 
$smarty = new classSmarty();
$smarty-&gt;caching = true;
$smarty-&gt;cache_lifetime = 10;
 
$template = 'smarty.html';
$cache_id = 'smarty|1337';
 
if(!$smarty-&gt;is_cached($template, $cache_id)) {
    $smarty-&gt;assign('time', date('H:i:s', time()));
    $smarty-&gt;assign('a', rand(1, 9999));
    $smarty-&gt;assign('b', rand(1, 9999));
    $smarty-&gt;assign('c', rand(1, 9999));
}
 
$smarty-&gt;display($template, $cache_id);

and works again!

And last but not least we want to delete all expired entries. Create a cronjob which is running every minute to do this.

I hope the blog helps you!