1

我想创建一个函数,如果第一次调用它,它的行为会有所不同,而在其余时间它的行为会有所不同。现在要做到这一点,我知道我可以使用“状态”变量。这里还提供了一些其他技术: 检查函数是否已被调用

但是我不知何故从一位同事那里得到了一个提示,即 debug_backtrace() 可以用来解决这个问题。我读过它,但不明白怎么做?此函数提供函数调用的堆栈跟踪。这如何判断该函数是否已被第一次调用?

让我困惑的确切代码在这里:

/**
 * Holds the states of first timers
 * @var array
 */
private static $firstTimeCSS=array();
private static $firstTimeJS=array();
/**
 * Tells whether it is the first time this function is called on 
 * ANY CLASS object or not. Useful for one-time scripts and styles
 * 
 * @param string $class name optional. Usually you should send __CLASS__ to this, otherwise the instance ($this) class would be used.
 * @return boolean
 */
final protected function IsFirstTime($class=null)
{
    $t=debug_backtrace();
    if ($t[1]['function']=="JS")
        $arr=&self::$firstTimeJS;
    else
        $arr=&self::$firstTimeCSS;


    if ($class===null)
        $class=$this->Class;
    if (isset($arr[$class]))
        return false;
    else
    {
        $arr[$class]=true;
        return true;
    }   
}
4

3 回答 3

4

我个人不明白这是怎么可能的,或者你为什么要这样做。我怀疑debug_backtrace()它比static变量贵得多,首先。

正如您所指出的,似乎在调用之间发生变化的唯一回溯特征是行号(从调用函数的位置)。而且,如果你在循环中运行这些函数,这甚至不会改变,因为它们都会在每次迭代时从同一行调用。

如果我是你,我会坚持使用状态变量;至于您的同事,如果您对它的工作原理感到好奇(我知道我是!),您也许可以要求他向您展示一个演示他的方法的代码。

编辑(来自评论):基本上,您同事的方法使用调用的类的键debug_backtrace()将布尔值存储在数组中。

用简单的英语,会发生以下情况:

  • 调用函数是否称为“JS”?
  • 如果是,则存储在一个 JS 标记的数组中;否则,使用带有 CSS 标记的数组。
  • 检查是否指定了一个类;如果不是,请使用此类。
  • 如果我们在标记数组中有给定类的布尔值,这不是第一次。
  • 否则,将给定类的布尔值设置为true。

我知道你在想什么:这毫无意义,它甚至不存储调用函数的名称!你是对的;这种方法不可扩展,而且开销很大。

如果您想执行此方法的操作,只需在相关类中使用静态变量来跟踪是否调用了函数。你同事的方法——很抱歉——是低效且无效的。

于 2013-07-14T02:59:35.810 回答
0

取一个隐藏的输入字段和

<input type="hidden" id="start_function_count" value="0"> 

然后调用一个函数

<li  onclick="myFunction('start_function_count')">

js函数

MyFunction(count_id) {
    var function_count = $("#"+count_id).val();
    if(function_count == 0){
        // CODE HERE for 1st time function call
        // SET HIDDEN FIELD
        $("#"+count_id).val(1);
    } else{
        // SECOnd time code;
    }
}
于 2020-03-19T07:04:29.753 回答
0

只需在函数中使用静态字段。这个静态字段只会被初始化一次并且不会被新的函数调用覆盖。

如果您在类方法中使用它,请注意每个继承的子类都有自己的版本。所以ParentClass更新的静态函数字段不会更新ChildClass extends ParentClass.

在行动中查看它https://ideone.com/iR7J5O

function beDifferentFirstTime() 
{
  static $firstTime = true;
  if($firstTime) {
     $firstTime = false;
     echo "I will say this only once, so listen carefully\n";
  }
  echo "The cabbage is in the cart. I repeat, the cabbage is in the cart.\n";
}
beDifferentFirstTime();
beDifferentFirstTime();
于 2020-03-19T08:44:46.013 回答