0

Problem sovled,thank you @SamuelElh for the tip ,so I relect it in the code.Transient turns out to be the right solution.

I wrote a function that adds links to existing post titles that occur in a post. For example, when you add a post to a site with the title "this is a title" and then the phrase "this is a title" shows up in the content of another post, it will automatically link to the previous post that holds that title.

My function works well (except for one thing which I will explain later):

function ji_title_auto_link($content){
if (is_single()) {//only auto link on post pages.
    global $post;
    global $wpdb;
 //retrieve all the post titles from the database,and this is where it goes nasty cause I have more than 50000 post!
 // UPDATE:Check for transient. If none, then execute $titledb
 if (false === ( $titledb = get_transient( 'titledb' ) )) {
 $titledb=$wpdb->get_results("SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish'");
  set_transient( 'titledb', $titledb, 12 * HOUR_IN_SECONDS );
}

foreach ($titledb as $key) {
    $titles=$key->post_title;//foreach all the titles
    $link=get_permalink();
    $replace='<a target="_blank" title='.$titles.' href="http://12reads.cn/wiki/'.$titles.'">'.$titles.'</a>';
    $titleself=get_the_title();//make sure it don't link itself
    $pos=strpos($content, $titles);
    if ($pos !== false) {
        $length=strlen($titles);
        if ($titles != $titleself) {
            $content=substr_replace($content, $replace, $pos, $length);
        }

        unset($key);
    }
}
//echo get_the_title();
return $content;
}else{return $content;}
 }
add_filter('the_content', 'ji_title_auto_link');

The problem with this function is that I have 50,000 plus posts on my site. Imagine that I have to retrieve 50,000 titles from the database using $wpdb->get_results. The result is a disaster! It slows down the post page instantly.

My question is how can I rewrite this function to save some database burden or is there even any other ways to achieve this?

  • 2
    Wow, you're selecting the whole titles every time! would be better if you select based on the content, or if you cache $titledb (with wp object cache or transients) for future. – Samuel Elh Jan 27 '17 at 10:07
  • how do I select base on the content? is that possible?? thank you. – 吉 宁 Jan 27 '17 at 10:13
  • You should intercept post saving and do this job only once. There are approriate hooks activating your code when user clicks Save button. – KAGG Design Jan 27 '17 at 11:33
  • you mean 'publish_post'? and wirte the auto link into the database permanently? – 吉 宁 Jan 27 '17 at 12:55
  • 1
    thank you @SamuelElh for the transient tip.Transient API is the solution here! – 吉 宁 Jan 28 '17 at 17:09
1
  1. Use a cache plugin (or write your own custom cache plugin) to server those posts.
  2. Set the cache plugin to update posts' contents whenever any other post title is updated / added. Or you can do this in a background process using cron.

This way your original content remains intact, but you still get quick response from the server.

  • NO,cache plugin like w3tc is not helping in this case.The right way is what @SamuelElh suggested:using wordpress transient API.Pls see the updates. – 吉 宁 Jan 28 '17 at 17:05
  • There is no right or wrong ways, there are many ways to do one thing. You can write a simple cache plugin that will cache content of every post/page and the use the_content filter to output from the cache. – Fayaz Jan 28 '17 at 21:46
  • Of course you can use transient API to save the cache of the title query & save the cache of content in post meta. The idea is you cache the results. – Fayaz Jan 28 '17 at 21:53
  • Thing is ,if I use a persist cache plugin, there willl be 50,000 times super slow browsing experience before the cache even work. But if transient,there will only be one. – 吉 宁 Jan 29 '17 at 3:28
  • Not necessarily. As I said, you can cache the final content with link in post meta & you can use that along with the transient call for titles + use a cron job to update the title result in transient & content cache in meta in the background before they expire - that way you'll not have a single super slow browsing experience. – Fayaz Jan 29 '17 at 4:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.