有没有推迟 PHP 代码执行的方法?

6
有没有推迟 PHP 代码的方法?
就像在 JavaScript 中我们使用 <script defer="defer"></script>。是否有办法在 PHP 代码中做到同样的效果?
更新: 这是我使用的代码:
说明:此代码位于我的侧边栏,加载时会导致网站停止 2-3 秒钟。我正在尝试跳过此过程,并在其余网站加载完毕后再加载此代码... 我也欢迎其他编码解决方案。
<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>

3
“相同”会是什么?因为 PHP 没有文档和 DOM 就绪等概念,所以它不能是“字面上”的相同。 - Jon
3
这没有任何意义。<script defer="refer">的意思是,可以在脚本加载时继续加载其他页面元素。另一方面,PHP在服务器上执行,通常是在任何东西到达浏览器之前执行。 - lanzz
无法记得 PHP 中是否存在这样的功能。但一个简单的解决方案是重新思考你的代码,开始重构它以提取你想要“延迟”执行的部分,并稍后或在最后执行它。像 JavaScript 中实际的延迟执行并没有太多意义。 - eddipedia
好的,这里是问题...我有一段PHP代码,用于从Google货币转换器获取信息。目前它放在我的侧边栏中,但会导致网站在2-3秒内停止加载,然后继续加载。因此,我正在尝试找到一种方法来跳过该部分的加载过程,并在网站完成加载后执行。我将在2分钟内更新问题并附上我的代码。 - Demilio
1
然后通过Ajax请求加载侧边栏,该请求针对专门执行该任务的不同PHP脚本。 - SirDarius
显示剩余3条评论
5个回答

6

在没有使用hack的情况下,唯一可维护的推迟PHP代码的方法是通过__destruct方法:

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))
    }
}

使用方法:

$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"; })

由于延迟栈是按照相反的顺序执行的,因此stdout将如下所示:

hi
closing DB connection
closing resource
bye

你也可以使用 register_shutdown_function


1

看起来你想要使用AJAX。简单来说:

  1. 不要在页面中包含有问题的代码;在代码结果应该出现的地方放置一些占位符(比如加载动画)。
  2. 取而代之,包含JavaScript代码,使其向服务器发出一个AJAX请求;服务器通过运行有问题的代码并返回一些结果(可能是纯HTML)来处理此请求。
  3. JavaScript代码获取此结果并将其合并到您的页面中,替换占位符。

如果您使用jQuery,则方便函数load是一个很好的起点。


抱歉,我在这方面有点新手...你有这方面的代码吗? - Demilio

1

两种选择:

  1. 使用 AJAX 在单独的请求中加载此内容,以避免影响页面加载速度。然而,由于这是不同的域,您将不得不绕过同源策略,例如使用 JSONP,因此如果处理不当,则会存在安全风险。建议使用 jQuery,如this tutorial所述。
  2. 在服务器上定期检索此数据并将其存储在数据库中,以便可以从那里加载。

无论哪种方式都可以,但如果数据量大和/或远程连接可能较慢,则 cron 选项可能更可取。


如果可以的话,我会使用JS,但我有点新手,你有一些代码可以让我看看/使用吗? - Demilio
教程和示例:http://viralpatel.net/blogs/jquery-ajax-tutorial-example-ajax-jquery-development/ - Matt Gibson

0
你可以尝试将这些 div 移动到页脚,并使用 JavaScript 将其移到合适位置。但是,这会破坏优雅的降级,因为如果用户没有启用 JS,则它将始终停留在页脚。另一方面,它将使您免于通过 AJAX 进行额外请求的麻烦。
如果使用 jQuery,代码可能是这样的:
<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>

另一个选项可能是:

  1. $from_currency的值“1”转换为$to_currency
  2. 将该比率存储在PHP变量$currency_ratio
  3. 对于所有计算,使用$currency_ratio比率,这样您就不需要为每个计算都进行一次CURL请求。

这样,您只需要进行一次CURL调用,而不是5次,这应该会显着加快速度。


这完全不是问题所在。 - Jon
@Jon 是的!如果页面在页脚停留几秒钟,那么没关系,因为用户不会注意到。在我看来,这比使用 AJAX 更好。 - frnhr

0

就像已经建议的那样,使用Ajax以异步方式加载内容。 但这是一个有关工作原理的例子。

有几种方法可以做到这一点,但最好的选择是使用JS库。 一个非常流行的是jQuery(也许您已经在使用它了?)

您可以像这样轻松地使用jQuery进行Ajax调用:

$.ajax({
  url: 'http://127.0.0.1/controller/someAction/param1',
  success: function(data) {
    $('.result').html(data);
    alert('Load was performed.');
  }
});

在这个例子中,我正在调用这个URL:http://127.0.0.1/controller/action/param1。当然,你可以使用任何URL。但是这里的重点是要确保它只返回你想看到的内容。因此它不应该返回整个页面(包括DOCTYPE和所有内容),而只需要像下面这样返回一些内容:

// 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);
}

而menu.phtml看起来像这样:

<div>
  <div> ... content ... </div>
</div>

现在回到 JS 代码。如果一切顺利,那么就应该触发 success 方法。所有内容都将在变量 data 中。所以你现在需要做的就是把数据放到正确的 DIV 中。这就是这行代码的作用:$('.result').html(data);。这将在名为 result 的 div 中放置加载的内容。
基本上这就是你需要做的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接