【问题标题】:Is there a way in PHP to calculate the checksum of a functions body? [duplicate]PHP中有没有办法计算函数体的校验和? [复制]
【发布时间】:2021-06-06 11:21:36
【问题描述】:

在 PHP 中有什么方法可以在运行时获取函数的校验和吗?

我想将它用于处理两个变量比较的函数,我会将变量 ids 和函数校验和存储在数据库中,这样就不会在每次运行脚本时重复昂贵的比较过程, 仅当比较两个变量的函数或任何变量发生变化时。

【问题讨论】:

  • 而不是 "checksum of the function"(无论你的意思是什么),存储函数的版本并将其与两个值一起传递以与功能。功能代码应该知道它的当前版本。每次以改变其行为或结果的方式修改函数代码时,都必须增加它。这种方法可确保在您升级到不同版本的 PHP 或重构代码时“函数的校验和”不会改变。
  • 通过校验函数,我的意思是获取函数的整个主体(代码或其他),并在其上运行md5(或任何其他字符串散列函数),这应该改变,每当函数主体中的某些内容发生变化时。 (即为其添加新空间或其他东西)。您提出的是容易出错的imo,因为如果开发人员在更改函数时忘记更新函数的版本,我的脚本将不会重新比较这两个数组。校验和方法减少了(不幸的是,没有完全消除)这个问题

标签: php checksum


【解决方案1】:

我不知道如何在 php 中获取函数体,但您可以将函数存储在它自己的文件中并校验和文件。

【讨论】:

  • 是的,作为替代解决方案,这会起作用,但我想将这个(和其他类似的)函数保留在一个单独的类中,以保持更有条理。基本上,我可以在所有地方都有 2-300 个这样的功能,如果只为此目的创建 2-300 个文件,那就有点过头了。
  • 您可以将文件解析为文本文件,将函数提取为字符串,然后对其进行哈希处理。
【解决方案2】:

使用反射 API 可以做到这一点,但它本身可能会很慢:

  1. 创建一个ReflectionFunction 对象
  2. 调用getFileName()并加载源代码,例如使用file_get_contents()file()(将文件拆分为行数组)
  3. 调用getStartLine()getEndLine(),并从源文件中提取这些行
  4. 这将为您提供函数的源代码,然后您可以对其进行哈希处理以形成您的缓存键

还有a library called BetterReflection,它从文件中加载源代码并在不执行的情况下对其进行解析,并且可以返回重新构造的源代码(即功能相同,但布局与原来的)。这可能有助于避免格式更改导致哈希更改,但速度会更慢。

如果你有大量的函数要散列,你可能想要制作一个构建脚本来加载整个类或文件,然后循环遍历它,生成每个函数的散列。然后,您可以将这些哈希值存储在查找表中(作为 PHP 或 JSON 数组保存在磁盘上),缓存代码可以使用该查找表按函数名称进行查找。

值得考虑一些可能更简单、更高效的替代方法:

  • 在应用程序版本上键入缓存。这可能会产生更多误报(不必要的重复工作),但不会出现误报(缓存保存时间过长)。
  • 在函数中手动增加版本。这是需要维护的更多工作,但如果做得正确,可以消除假阴性和假阳性。

【讨论】:

  • 有问题的函数不会,并且通常可能不会调用其他函数,所以这不是问题。错误地使缓存无效对我们来说不是一个主要问题(如果定期再次执行操作,而没有对函数进行任何真正的更改,我可以忍受),更重要的是错误地验证它。您能否举一个具体的例子说明我应该从反射 API 中使用哪种方法?
  • 我想知道,当函数体中的某些内容发生变化时,序列化的ReflectionFunction 会发生变化吗?或者对此没有任何保证?
  • 我已经重写了答案,但后来意识到有人已经指出了上面的重复。
猜你喜欢
  • 1970-01-01
  • 2015-04-14
  • 2012-05-20
  • 1970-01-01
  • 2023-03-22
  • 2021-05-11
  • 2018-07-30
  • 2015-09-06
  • 1970-01-01
相关资源
最近更新 更多