0

I am totally new to the wordpress world so excuse me if my question is not totally clear to you...

I wanted to implement the following scenario for my website, The case was to call an external api and get some data visitor depended.

In the begging I have added a custom function with add_action('init,'function_name',1) which I have defined in the functions.php

I was setting the data of the api as global and was using them in the proper location of the site with success.But after checking the credit usage i found out the the functions.php runs multiple time for a single page.

After adding an error_log(debug_backtrace()[1]['file']) to the functions.php it shows that the file functions.php is called multiple times which arised from the wp-confing.php line:require_once( ABSPATH . 'wp-settings.php' );

For temporary solution i have disabled the add_action('init'....) and added the run of the function to each type of page (page-home ,single, etc), but as far as i understand this is not a proper solution.

The code I was using was :

    add_action('init',fuctionname,1);
    function fuctionname(){
       global $data;
       //have tried with the !isset() but as functions.php 
       //is called multiple times this wont work and credits will be used
       // Api call
       $data_api= $api_object->value1;
    }

Therefore my questions are:

  1. Why the functions.php of theme is loaded so many times? where should i take a look?
  2. Which is the proper way to do the scenario I described? Run a function once when user/visitor enters the site and then use either global or session variable
5
  • functions.php running multiple times in the same request is not normal. Are you sure you're not including other requests such as REST API or Admin AJAX requests in that figure? Keep in mind that making a HTTP request on a frontend request carries a massive performance hit regardless of the CMS you use, your site can never be faster than the speed of that external API. I'd also avoid global variables in any programming language – Tom J Nowell May 4 '20 at 14:30
  • Also, how are you testing that functions.php runs more than once? PHP sessions won't work on a lot of hosts either but they're not necessary as WP uses cookies for sessions. functionname also needs to be wrapped in quotes, the same as any PHP callable would be. – Tom J Nowell May 4 '20 at 14:34
  • @TomJNowell For the multiple run of the functions.php i have just adding an error_log(debug_backtrace()[1]['file']) at the end of the functions.php , the certain message was print multiple time and then i started tracking the wp-config.php – Kap40 May 4 '20 at 14:57
  • @TomJNowell about the quotes you are correct, its my mistake i did not write it properly in the example... – Kap40 May 4 '20 at 14:58
  • @TomJNowell So how can i run the desired function whenever user visits the site (in any page) and then grab it at the desired location of code? – Kap40 May 4 '20 at 15:00
0

Why the functions.php of theme is loaded so many times? where should i take a look?

It doesn't, that's not how WP themes work. If you're manually loading functions.php then that would be why, but you shouldn't do that.

WP loads functions.php once per HTTP request. Keep in mind that a browser might make multiple requests. E.g. it might load the page, then make AJAX requests in javascript. So if your load the site, and the site makes 5 AJAX calls, that's 6 requests not 1 request, so functions.php and WP are laoded 6 times.

The only other thing I can think of, is that you've modified WordPress itself to get the changes you wanted, never do this. Use themes plugins actions and filters to change the behaviour of WordPress.

Which is the proper way to do the scenario I described? Run a function once when user/visitor enters the site

You would need to leave some kind of indicator that the visitor has been there before, aka a cookie.

I've separated the last part of this question into its own thing as it suggests you have a fundamental misunderstanding of how PHP programs work.

and then use either global or session variable

A PHP session is a bad idea, as it still involves a cookie on the user side, so it does not bypass cookie laws. It also won't work on a lot of hosts as they'll either turn this off, or their caching and optimisations would be incompatible.

So why not use a global variable?

Because that's not how PHP works. PHP programs aren't like a Node or a Java CMS that runs in the background. There's no persistant program.

Everytime you make a request, a PHP process is spun up, from scratch, each request is a blank slate. No variables you store in PHP will be available, and all files are loaded.

WordPress will try to mitigate this by being smart about how it loads things from the database, providing APIs for persistent storage, etc. If you have a memcached or Redis server you can install an object cache that can give a huge performance boost, but you can't just declare a variable to have a value and expect it to still have that value on the next page load. At the end of the request, the program ends, it's all wiped clean.

So what are global variables in PHP?

The global keyword is a way to make a variable available everywhere without any structure. It's a crude way of pulling something out of thin air that can cause lots of problems. It's not just a feature of PHP applications either, the scourge of global state is known in many programming languages. Look at the Google Clean Code lectures on global state to learn about the horrors and dangers.

You'll also notice some WP developers are big fans of "singletons". This is when they take things and put them in a class so it looks like it's object oriented, but it isn't. Then they give it a static method so they can access it from anywhere like a global variable. It's a well known anti-pattern and bad practice.

So What Should You Do?

That depends on what it is that you're doing, your question is very light on details.

If you want to know if a user has visited the site before:

  • set a cookie if no cookie is set
  • if no cookie is set then they've never been here before
  • if a cookie was set, then this isn't the first time they've visited

None of this is WordPress though, it would be the same answer for all CMS' and languages.

Note that this is not foolproof, anybody can:

  • visit in incognito mode
  • turn off cookies in their browser
  • send a GDPR request demanding all the data you have on them, and to be removed
  • use someone elses device
  • use a different browser

As for making a remote API request:

  • Don't do it in PHP on the frontend, this is will make your site ultra slow as it has to wait for the remote server before it can reply to the user with the page
    • expect a major SEO hit as a result
  • Do it in javascript. That's how google analytics handles things.
    • This opens up additional options for testing if the user has been to the site before, such as checking localstorage instead of using cookies
    • This is significantly faster, the server will never be able to match this speed if done correctly
    • Frontend javascript doesn't need to have anything to do with WordPress, so you don't have to confine your research or the help you get specifically to WP
1
  • Great Tom, thank you for your answer. I got the general idea of the whole situation. I will check out the solution with the frontend javascript you mentioned .. please check the new info i added to my question – Kap40 May 4 '20 at 15:59

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.