{"id":1411,"date":"2010-05-18T15:26:36","date_gmt":"2010-05-18T13:26:36","guid":{"rendered":"http:\/\/planetozh.com\/blog\/?p=1411"},"modified":"2010-05-18T16:45:21","modified_gmt":"2010-05-18T14:45:21","slug":"overview-of-wordpress-transients-api","status":"publish","type":"post","link":"https:\/\/planetozh.com\/blog\/2010\/05\/overview-of-wordpress-transients-api\/","title":{"rendered":"Overview of WordPress&#8217; Transients API"},"content":{"rendered":"<p>There&#39;s a cool (and underused by plugins) API in WordPress: the <a href=\"http:\/\/codex.wordpress.org\/Transients_API\">Transients API<\/a>. Transients are temporary options, <em>ie<\/em> options set with an expiration time. Anytime you&#39;re <a href=\"https:\/\/planetozh.com\/blog\/2009\/05\/handling-plugins-options-in-wordpress-28-with-register_setting\/\">storing options<\/a> and they have a short life span, you should use transients instead.<br \/>\n<!--more--><\/p>\n<p>Disclaimer: I, for one, am totally underusing this API too, as it is rather new (it was introduced in WP 2.8) and I didn&#39;t update my plugins which could use it. Hopefully if you learn anything in this article, you will update your code :)<\/p>\n<h2>Transients functions<\/h2>\n<p>Basically transients are options, so their API is very similar to the Options API. The three functions you&#39;ll want to use are: <tt>set_transient()<\/tt>, <tt>get_transient()<\/tt>, <tt>delete_transient()<\/tt>.<\/p>\n<div id=\"ig-sh-1\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #666666;font-style: italic\">\/\/ Save a transient to the DB<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">set_transient<span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$transient_name<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #000088\">$transient_value<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #000088\">$expiration<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #666666;font-style: italic\">\/\/ Get value of a transient from the DB<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #000088\">$value<\/span> <span style=\"color: #339933\">=<\/span> get_transient<span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$transient_name<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #666666;font-style: italic\">\/\/ Delete a transient from the DB<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">delete_transient<span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$transient_name<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>Things to do or know:<\/p>\n<ul>\n<li>Let WP do the dirty job: don&#39;t escape things for SQL, don&#39;t serialize arrays<\/li>\n<li>Give your transients unique and self explanatory names. <a href=\"http:\/\/www.andrewnacin.com\/2010\/05\/11\/in-wordpress-prefix-everything\/\">Prefix them just as anything else<\/a>.<\/li>\n<li>When you <tt>get_transient()<\/tt> and it has expired or has never been set before, the function returns <tt>false<\/tt><\/li>\n<li>In case you want to manually check the DB, saving a transient named &#39;<tt>ozh<\/tt>&#39; adds two entries in the option table: <tt>_transient_ozh<\/tt> storing the value, and <tt>_transient_timeout_ozh<\/tt> with the Unix timestamp of the expiration date<\/li>\n<li>Transients don&#39;t clutter the DB: when you fetch a transient value, if it has expired it is removed from the database<\/li>\n<\/ul>\n<h2>Using transients: an example<\/h2>\n<p>Let&#39;s make a simple plugin that displays the IPs of our last 10 visitors: this value is by essence temporary, and we will store it in a transient with a 3 minutes expiration.<\/p>\n<p>The plugin will do the following:<\/p>\n<ol>\n<li>Store last 10 visitors&#39; IPs in an array<\/li>\n<li>Get visitor&#39;s IP and check if it&#39;s in the array already<\/li>\n<\/ol>\n<p>This whole simple plugin is just one function:<\/p>\n<div id=\"ig-sh-2\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #666666;font-style: italic\">\/\/ Get visitor IP, update and return list<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #000000;font-weight: bold\">function<\/span> wp_ozh_slvc<span style=\"color: #009900\">&#040;<\/span><span style=\"color: #009900\">&#041;<\/span> <span style=\"color: #009900\">&#123;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #000088\">$ip<\/span> <span style=\"color: #339933\">=<\/span> <span style=\"color: #000088\">$_SERVER<\/span><span style=\"color: #009900\">&#091;<\/span><span style=\"color: #0000ff\">'REMOTE_ADDR'<\/span><span style=\"color: #009900\">&#093;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #000088\">$visitor_ips<\/span> <span style=\"color: #339933\">=<\/span> get_transient<span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #0000ff\">'ozh_livecounter'<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #b1b100\">if<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #009900;font-weight: bold\">false<\/span> <span style=\"color: #339933\">==<\/span> <span style=\"color: #000088\">$visitor_ips<\/span> OR <span style=\"color: #339933\">!<\/span><span style=\"color: #990000\">in_array<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$ip<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #000088\">$visitor_ips<\/span> <span style=\"color: #009900\">&#041;<\/span> <span style=\"color: #009900\">&#041;<\/span> <span style=\"color: #009900\">&#123;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666;font-style: italic\">\/\/ our transient has expired (or has never been set) or doesn't contain this IP<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #000088\">$visitor_ips<\/span><span style=\"color: #009900\">&#091;<\/span><span style=\"color: #009900\">&#093;<\/span> <span style=\"color: #339933\">=<\/span> <span style=\"color: #000088\">$ip<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666;font-style: italic\">\/\/ just keep at most last ten entries<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #b1b100\">if<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #990000\">count<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$visitor_ips<\/span> <span style=\"color: #009900\">&#041;<\/span> <span style=\"color: #339933\">&gt;<\/span> <span style=\"color: #cc66cc\">10<\/span> <span style=\"color: #009900\">&#041;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #990000\">array_shift<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #000088\">$visitor_ips<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666;font-style: italic\">\/\/ store this transient with a 3 minutes expiration<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; set_transient<span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #0000ff\">'ozh_livecounter'<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #000088\">$visitor_ips<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #cc66cc\">60<\/span><span style=\"color: #339933\">*<\/span><span style=\"color: #cc66cc\">3<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #009900\">&#125;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; <span style=\"color: #b1b100\">return<\/span> <span style=\"color: #990000\">join<\/span><span style=\"color: #009900\">&#040;<\/span> <span style=\"color: #0000ff\">', '<\/span><span style=\"color: #339933\">,<\/span> &nbsp;<span style=\"color: #000088\">$visitor_ips<\/span> <span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span><\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #009900\">&#125;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>And that&#39;s it. Now in a template PHP file such as <tt>sidebar.php<\/tt> just use the following:<\/p>\n<div id=\"ig-sh-3\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #000000;font-weight: bold\">&lt;?php<\/span> <span style=\"color: #b1b100\">echo<\/span> <span style=\"color: #0000ff\">'Currently online: '<\/span><span style=\"color: #339933\">.<\/span>wp_ozh_slvc<span style=\"color: #009900\">&#040;<\/span><span style=\"color: #009900\">&#041;<\/span><span style=\"color: #339933\">;<\/span> <span style=\"color: #000000;font-weight: bold\">?&gt;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<div class=\"download\">\nDownload the plugin <a href=\"https:\/\/planetozh.com\/blog\/wp-content\/uploads\/2010\/05\/ozh-simple-live-visitor-counter.php_.txt\">ozh-simple-live-visitor-counter.php.txt<\/a><br \/>\n(save as .php then put in your plugins folder)\n<\/div>\n<p>As you can see the plugin is as basic and simple as it can be. Pushing things further you would widgetize the output for easier integration into themes, make smarter IP detection to check proxies and filter search engine robots out, implement a country detector based on the IP and display cute tiny flags, add an uninstall.php file with a call to <tt>delete_transient( 'ozh_livecounter' );<\/tt> to make sure things are clean when uninstalled, and much more.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There&#39;s a cool (and underused by plugins) API in WordPress: the Transients API. Transients are temporary options, ie options set with an expiration time. Anytime you&#39;re storing options and they have a short life span, you should use transients instead.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[255,2,85,372,245],"class_list":["post-1411","post","type-post","status-publish","format-standard","hentry","category-published","tag-api","tag-code","tag-plugins","tag-transients","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/1411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/comments?post=1411"}],"version-history":[{"count":0,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/1411\/revisions"}],"wp:attachment":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/media?parent=1411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/categories?post=1411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/tags?post=1411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}