Is there a way to defer PHP code?
Is there a way to defer PHP code?
As in javascript, we use <script defer="defer"></script> . Is there a way to do the same with PHP code?
UPDATE: Here is the code I'm using:
Info: This code is located on the sidebar and causes the website to stop for 2-3 seconds at startup. I am trying to skip this prosus and load this code when the rest of the site has loaded. I am also open to other coding programs.
<div style="padding:5px;"> <?php function currency($from_Currency,$to_Currency,$amount) { $amount = urlencode($amount); $from_Currency = urlencode($from_Currency); $to_Currency = urlencode($to_Currency); $url = "http://www.google.com/ig/calculator?hl=en&q=$amount$from_Currency=?$to_Currency"; $ch = curl_init(); $timeout = 0; curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)"); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); $rawdata = curl_exec($ch); curl_close($ch); $data = explode('"', $rawdata); $data = explode('"', $data['3']); $var = $data['0']; return round($var,1); } ?> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 USD er <?php echo currency("USD","NOK",1); ?> NOK<br /> </div> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 EUR er <?php echo currency("EUR","NOK",1); ?> NOK<br /> </div> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 GBP er <?php echo currency("GBP","NOK",1); ?> NOK<br /> </div> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 SEK er <?php echo currency("SEK","NOK",1); ?> NOK<br /> </div> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 DKK er <?php echo currency("DKK","NOK",1); ?> NOK<br /> </div> </div> Two options:
- Use AJAX to load this into a separate request so that it does not delay page loading. However, since this is a different domain, you will have to crack the same origin policy, for example. using JSONP , so it can be complicated and have security implications if it is done poorly. Try using jQuery, according to this tutorial .
- Run a cron job that periodically retrieves this data on the server and stores it in your database so that it can be downloaded from there.
In any case, this is normal, but if the data volume is large and / or the remote connection may be slow, the cron option may be preferable.
The only supported way to defer PHP code (without hacks) is the __destruct method:
class App { protected $deferredStack = []; public function __destruct() { $this->runDeferredStack(); } public function defer(callable $deferred){ $this->deferredStack[] = $deferred; } protected function runDeferredStack() { array_map('call_user_func', array_reverse($this->deferredStack)) } } Using:
$app->defer(function(){ echo "bye"; }) // code that opens a resource here... $app->defer(function(){ echo "closing resource"; }) // code that opens DB connection here... $app->defer(function(){ echo "closing DB connection"; }) $app->defer(function(){ echo "hi"; }) Since the deferred stack is executed in the reverse order, stdout will be:
hi closing DB connection closing resource bye You also use register_shutdown_function
Sounds like you want AJAX. Shortly speaking:
- Do not include the violation code on your page; place some placeholder (e.g. loading animation) where the code results appear.
- Instead, include JavaScript code that returns an AJAX request to your server; the server processes this request by running a violation code and returning some result (possibly direct HTML).
- JavaScript code accepts this result and includes it on your page, replacing the placeholder.
If you use jQuery, the convenient load function is a good place to start.
As suggested here, use Ajax to load content asynchronously. But here is an example of how this works.
There are several ways to do this, but it is best to use the JS library. JQuery is very popular (maybe you are already using this?).
You can easily make an Ajax call using jQuery as follows:
$.ajax({ url: 'http://127.0.0.1/controller/someAction/param1', success: function(data) { $('.result').html(data); alert('Load was performed.'); } }); In this example, I am calling this URL: http://127.0.0.1/controller/action/param1 . Of course you can use any url you want. But the point here is that you have to make sure that it returns only what you want to see. Therefore, it should not return the whole page (DOCTYPE and all), but only something like:
// This is obviously just fictional, i have no idea how your php code looks like public function someAction($param1) { $menu = $this->getPartialView('menu.phtml'); $this->view->parse($menu); } And menu.phtml looks something like this:
<div> <div> ... content ... </div> </div> Now back to the JS code. If all goes well, then the success method should be run. All content will be in the data variable. Therefore, all you have to do now is put this data in the correct DIV. For this line: $('.result').html(data); . This will put the loaded content in a div with the class name result .
That is basically all you need to do.
You might want to move these divs to the footer and drag them into place using JavaScript. Although, this will slow down the graceful degradation, as it will remain in the footer if the user does not have JS. On the other hand, this saves you from having to make an additional request through AJAX.
If you use jQuery, it will be something like this:
<div class="footer_calcs"> <div style="padding:2px; border-bottom:1px solid #EFEFEF;">1 USD er <?php echo currency("USD","NOK",1); ?> NOK<br /> </div> ... </div> <script ...> $(function(){ $('.footer_calcs').children().appendTo( $('#id_of_destination_in_sidebar') ): }); </script> Another option might be:
- converts the value "1" in
$from_currencyto$to_currency - save this relation in PHP var
$currency_ratio - use the
$currency_ratiocoefficient for all calculations, so you donβt need to make a CURL request for Google for each of them.
Thus, you only make one CURL call instead of 5, which should speed up the process significantly.