Php 如何知道函数是否第一次调用

Php 如何知道函数是否第一次调用,php,Php,我想创建一个函数,这样,如果第一次调用它,它的行为会有所不同,其余时间它的行为也会有所不同。现在要做到这一点,我知道我可以使用“state”变量。这里还介绍了一些其他技术: 然而,我不知怎的从一位同事那里得到了一个提示,debug_backtrace()可以用来解决这个问题。我读过,但不明白怎么读?此函数提供函数调用的堆栈跟踪。如何判断函数是否第一次被调用 让我困惑的确切代码如下: /** * Holds the states of first timers * @var array *

我想创建一个函数,这样,如果第一次调用它,它的行为会有所不同,其余时间它的行为也会有所不同。现在要做到这一点,我知道我可以使用“state”变量。这里还介绍了一些其他技术:

然而,我不知怎的从一位同事那里得到了一个提示,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;
    }   
}

我个人不明白这是怎么可能的,也不明白你为什么要这样做。首先,我怀疑
debug\u backtrace()
静态变量要昂贵得多

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

  • 示范1(个人电话):
  • 演示2(循环):
如果我是你,我会坚持使用状态变量;至于您的同事,如果您对其工作原理感到好奇(我知道我是!),您可能会要求他向您展示一个演示其方法的代码

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

用通俗易懂的英语说,发生的情况如下:

  • 调用函数名为“JS”吗
  • 如果是,则存储在JS标记的数组中;否则,请使用CSS标记的数组
  • 检查是否指定了一个类;如果不是,请使用此类
  • 如果标签数组中给定类有一个布尔值,这已经不是第一次了
  • 否则,将给定类的布尔值设置为true
我知道你在想什么:这毫无意义,它甚至没有存储调用函数的名称!你是对的;此方法不可扩展,并且具有巨大的开销


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

获取一个隐藏的输入字段并

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

只需在函数中使用静态字段。此静态字段仅初始化一次,在新函数调用时不会被覆盖

如果在类中使用此方法,请注意每个继承的子类都有自己的版本。因此,在
ParentClass
中更新的静态函数字段不会更新
ChildClass扩展ParentClass
中的静态函数字段

看到它在行动吗


您是否尝试过两次运行函数并比较debug_backtrace的输出?是的。输出仅在数组[0]['Line']中不同,即只有行号发生了变化……我想这是正确的,因为堆栈跟踪没有改变。它仍然在用相同的规则和路径调用相同的函数。@user1834562啊,好的。我已经更新了我的帖子,提供了一些相关信息。我真的很难理解为什么你共享的函数对任何人都有用。我的问题是,当他检查function name=“JS”时,那一行如何显示这个函数以前是否被调用过。它只是告诉我们“JS”函数是从某处调用的。@user1834562确切地说,它只存储“调用的函数<代码>JS
”和“未调用的函数<代码>JS”的每个类的真值。正如我在编辑中所说的,这个方法是不可扩展的(因为您刚才描述的原因)。好的。现在我终于明白了。这里没有什么新鲜事。正如您所说,“首次使用”的检查不是通过debug_backtrace()完成的,而是通过在静态数组中存储令牌来完成的。谢谢!!:)没问题!一般来说,如果某个答案帮助您解决了问题,您可以单击答案左侧的复选标记将其标记为“正确”。快乐编码!:)永远不要用客户端检查取代服务器端检查。客户机可以将任何内容发送到服务器、绕过任何验证或表单本身。永远不要信任客户机,即使你认为你可以控制它运行的代码
<li  onclick="myFunction('start_function_count')">
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;
    }
}
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();