函数数组的替代方案?

2024-04-16

我正在编写一个应用程序(php),它需要一个很长的列表相似但不同的功能,由一组按键调用:

$functions = [
    "do this" => function() {
        // does this
    },
    "do that" => function() {
        // does that
    }
] 
etc.

我选择将相似的函数放在一个数组中,因为它们不相似enough- 使用一个充满条件语句的大函数获得相同的结果是行不通的。和我确实需要只能通过按键呼叫他们, 例如:

$program = ["do this", "do that", "do this"];
foreach ($program as $k => $v) {
    $functions[$v]();
}

问题是这个函数数组结构引起了很多问题,例如我遇到了困难从一个数组函数调用另一个数组函数,例如这不起作用:

"do that" => function() {
    $functions["do this"]();
}

也不是这个:

"do that" => function() {
    global $functions;
    $functions["do this"]();
}

or this:

"do that" => function($functions) {
    $functions["do this"]();
}

$functions["do that"]($functions);

我想我可以拥有一个很长的巨大功能switch语句:

function similar_functions($key) {
    switch ($key) {
        case "do this":
            // does this
        break;
        case "do that":
            // does that
        break;
    }
}

但这似乎并不是一个好的做法。或者也许是这样?

那么,我有什么选择呢?我应该采用 switch 结构吗?或者还有其他更好的解决方案吗?


在 php 中,闭包对于性能和内存使用来说是昂贵的。过程式编码引发了一大堆泥巴、意大利面条式代码和其他反模式。开关结构很难测试,而且违反了OCP http://en.wikipedia.org/wiki/Open/closed_principle.

你应该更喜欢 OOPSOLID http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29避免冗余的方式,提高可扩展性和可维护性。这是提供一组可重用函数的最佳实践。 您还可以将代码分成层和模块,以降低复杂性并提高可互换性。

在你的情况下,你的课程可以实现__invoke http://www.php.net/manual/de/language.oop5.magic.php#object.invoke将其称为可调用的,并且您的键可以是这些类的完全限定名称空间,因此您可以像函数一样调用它。 从现在开始,您还可以使用继承、多态性或复合、装饰器等设计模式来重用其他函数或添加函数。

这是一个简单的例子..

<?php
use Foo\Bar;

class This
{
    public function __invoke()
    {
        $this->execute();
    }

    public function execute()
    {
        /* ... */
    }
 }

class That extends This
{
    public function execute()
    {
        /* ... */
    }
 }

$namespaces = array("\Foo\Bar\This", "\Foo\Bar\That"); 
foreach ($namespaces as $fullQualifiedNamespace) {
    /** @var callable $fullQualifiedNamespace */
    $fullQualifiedNamespace(); 
}

通过实现 This 和 That 的特定接口也可以实现此行为。 在迭代中,您可以检查调用已定义合约的接口。或者您构建一个进程类,您可以在其中添加实现此接口的对象。 Process 类可以执行所有附加对象(责任链 http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern).

我更喜欢责任链模式,这是大多数开发人员可以理解的,但事实并非如此magic就像 PHP 的 __invoke 拦截器一样。在工厂中,您可以定义链,并且可以定义链或附加链对象的其他依赖项。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数数组的替代方案? 的相关文章

  • Yii 使用 ajax 进行分页

    我需要使用ajax启用分页 我的代码 控制器 更新内容ajax function actionIndex dataProvider new CActiveDataProvider News array pagination gt array
  • Android:如何在播放媒体(mp3)时在特定毫秒内显示文本

    我正在尝试做一个类似卡拉 OK 的应用程序 我想在某一毫秒到来时显示一个或多个单词 例如 1148 毫秒 gt 打印 尼古拉斯 1826 毫秒 gt 打印 是 2766 毫秒 gt 打印 旧 ms gt 显示 这是我的代码 包 com ex
  • 解析,用三点参数替换

    让我们考虑一个典型的deparse substitute R call f1 lt function u x y print deparse substitute x varU vu varX vx varY vy f1 u varU x
  • FPDI/FPDF:水印和打印多页

    我修改了这个堆栈问题 当用户尝试下载文件时在 pdf 文件上应用水印 https stackoverflow com questions 3983432 applying watermarks on pdf files when users
  • PHP严格标准:声明应该兼容

    我有以下类层次结构 class O Base class O extends O Base abstract class A Abstract public function save O Base obj class A extends
  • 扩展蓝图类?

    我想覆盖timestamps 函数中发现Blueprint班级 我怎样才能做到这一点 e g public function up Schema create users function Blueprint table table gt
  • 蛋糕控制台 2.2.1:烘焙错误

    运行 MAMP 的 OSX 机器 CakePHP 2 2 1 已正确安装和配置 这意味着当我浏览到 Index php 文件时 所有绿色条都显示出来 我已经完成了博客教程 并且正在开发我的第二个应用程序 其中脚手架已启动并运行 现在我第一次
  • 如何实现返回“弹出”元素(即数据/值)的“Pop”函数? (链表堆栈)

    对于如何实现同时弹出元素并将其作为返回值返回的单个函数感到困惑 到目前为止 我所看到的都是 pop 函数 它们返回指向堆栈新头的指针 这是一个开始 但是 define VALUE int typedef struct node t VALU
  • 如何在原则 2 迁移中删除外键

    我想在原则 2 迁移中删除外键 但没有 dropForeignKeyConstraint 有谁知道怎么丢掉吗 public function down Schema schema table schema gt getTable table
  • 学说迁移后备

    我们正在使用原则迁移 当迁移包含多个操作并且其中一个操作失败时 通常会出现问题 例如 如果迁移添加了 5 个外键 其中第 5 个失败 而字段长度不同 则修复字段错误并重新生成迁移不会not修复整个问题 而现在出现一个与 4 个密钥已存在有关
  • “使用未定义常量”注意,但该常量应该被定义

    共有三个文件 common php controller php 和 user php 文件 common php 如下所示 文件controller php看起来像 文件 user php 如下所示 执行脚本时 会给出通知 注意 使用未定
  • 在 PHP 中使用 phpseclib 时出现 RSA 问题

    我正在尝试在 phpseclib 中使用 RSA 实现 我认为在函数中执行一次代码并重新使用该函数会更容易 当我尝试向代码发送短信时 我收到一条错误消息 提示 解密错误 测试还让我意识到每次代码运行时密文都是不同的 所以我显然在那里做错了什
  • 在 Wordpress 站点中进行 AJAX 调用时出现问题

    我在使用 Wordpress 站点功能的 AJAX 部分时遇到了一些问题 该功能接受在表单上输入的邮政编码 使用 PHP 函数来查找邮政编码是否引用特定位置并返回到该位置的永久链接 我的第一个问题是关于我构建的表单 现在我的表单操作是空白的
  • jQuery Mobile 表单验证

    我有一个移动网站 除了验证之外一切都工作正常 基本上我希望从用户那里获取值 然后在单独的页面 process php 上处理它们 但是 在这样做之前 我需要检查以确保字段已填充 我已经研究了几种方法来做到这一点 但似乎没有一种有效 我现在有
  • PHP 中只保留数组的前 N ​​个元素? [复制]

    这个问题在这里已经有答案了 有没有办法只保留数组的前 N 个 例如 10 个 元素 我知道有array pop 但是有没有更好 更优雅的方法呢 您可以使用array slice http php net array slice or arr
  • 如果循环中内存超出,我可以在 for 循环中抛出异常吗?

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如何处理 foreach 循环中发生
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • 使用正则表达式提取两个短语之间的所有单词[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下正则表达式提取两个短语之间的所有单词 b item W w W 0 2 1 one W w W 0 3 business b b item W w W 0 2 3 three W w W 0 3
  • Magento - 自定义支付模块

    这是一个非常普遍的问题 但这里是 我正在尝试在 Magento 中创建一个自定义支付模块 我创建了一个 常规 模块 可以连接到 Magento 事件 观察者模型 但是我如何告诉 Magento 将模块视为支付模块 以便它显示在管理后端和结账
  • 如何使用 PHPExcel 库从 Excel 获取日期

    我正在尝试使用 PHPExcel 从 Excel 获取日期 但我没有得到日期 我得到的字符串值不是 1970 以来的秒数 我尝试过的代码是 InvDate trim excel gt getActiveSheet gt getCell B

随机推荐

  • 表单标签的 CSS 样式

    据我所知 一个
  • Java、HashMap 和使用字符串作为键 - 字符串值是否会存储两次?

    如果我有一个如下所示的 HashMap HashMap
  • Viewpager 延迟加载数据

    ViewPager有一个公共函数setOffscreenPageLimit http developer android com reference android support v4 view ViewPager html setOff
  • MVC 3 列表的不引人注目的验证

    Question 我创建了一个服务器端属性级别验证属性 但我没有将其应用于单个字段 而是将其应用于列表 这使我能够从整体上验证模型 我现在需要知道如何使用 MVC 3 中内置的不显眼的客户端验证将其转换为工作 我当前的代码如下来说明我的问题
  • div背景图片+jquery的幻灯片

    我在标题处有一个大的 div 元素 div 中有很多文本内容和一些框 我有一个大的 img 作为这个 div 的背景 现在我需要为这个 div 的背景制作一个幻灯片 如何为 div 的背景图像制作幻灯片 我研究了很多 但找不到任何东西 多谢
  • Bash if 语句中何时需要方括号?

    通常 我在 if 语句中使用方括号 if name Bob then 但是 当我检查是否grep成功了我不使用方括号 if grep q text file then 什么时候需要方括号if陈述 方括号是同义词test命令 一个if语句检查
  • 分层代码优先 EF 绑定到 WPF Treeview...不可能

    在过去 我不得不求助于使用数据集和数据表 因为使用绑定来做到这一点仍然让我困惑 顶层 我在 VB 2012 中创建了一系列类 对它们进行了注释 并使用 Code First 在 EF6 中创建了 EF 模型 这个想法是表示路由器配置 配置的
  • 随机值生成 JavaScript

    我有一些代码用于将数组中的随机值存储到变量中 如下所示 Quest value1 value2 value3 value4 var random Math floor Math random Quest length var questio
  • 将控制台窗口添加到 ASP.NET Core 应用程序

    我有一个 ASP NET Core 2 0 应用程序在 NET Core 2 0 中的 Windows 上运行 命令行 C Program Files dotnet dotnet exe 执行 C Users zippy documents
  • 如何在 mysql 查询中将行放在顶部。

    您好 我的 SQL 表中有 100 条记录 我想按名称对它们进行 ASC 排序 但我需要在所有记录 nr 43 之上添加一条记录 有没有办法我可以先拉出这个记录 43 然后再按名称按 ASC 顺序排列其他所有内容 技巧是在一个查询中完成它
  • SSL 会话票证与会话 ID

    为了提高不保留 短 连接的 SSL 握手性能 有两个广为人知的独立功能 TLS 会话 ID TLS 会话票证 如果有很多短连接会话 就性能开销而言 哪种机制更可取并且应该使用 我知道服务器需要缓存会话 ID 并且在负载平衡的情况下会话票证也
  • 不在 In SQL 语句中?

    我在Excel中有一组大约5000个ID 在表中我有大约30000个ID 如果我在SQL语句中使用 In 条件 我将从Excel中拥有的ID中获得大约4300个ID 但是如果我将 Not In 与 Excel id 一起使用 我已经获得了大
  • node.js axios 下载文件流和 writeFile

    我想下载一个 pdf 文件axios并保存在磁盘 服务器端 上fs writeFile 我努力了 axios get https xxx my pdf responseType blob then response gt fs writeF
  • 四元数到欧拉角算法 - 如何转换为“Y = Up”和旋手性之间的转换?

    我有一个在四元数和欧拉角之间转换的算法 public static Vector3 ToEulerAngles this Quaternion q Store the Euler angles in radians Vector3 pitc
  • 在不同的数据集上运行经过训练的机器学习模型

    我是机器学习的新手 正在尝试在另一个相同格式的数据集上运行一个简单的分类模型 该模型是我使用 pickle 训练和保存的 我有以下 python 代码 Code Training set features pd read csv Data
  • 从 std::string 中提取(第一个)UTF-8 字符

    我需要使用一个PHP mb strtoupper 函数的 C 实现 http www zedwood com article cpp utf8 mb strtoupper function模仿维基百科的行为 我的问题是 我只想喂一个sing
  • 如何在 Android Canvas 上使用大量图元绘制游戏

    我在游戏的每一帧中画了很多线条矩形 这是老式手持电子游戏的娱乐 那些具有用于主游戏的原始点阵显示和用于文本或某些图像的自定义图像的内容 我在虚拟点阵屏幕上有 20x20 大 像素 我还在屏幕上绘制了一些 7 段显示和其他一些东西 根据Tra
  • 更改“corrplot()”中有意义的 pch 符号的位置?

    下面的脚本生成一个图 其中表示重要性的 pch 符号与 r 值重叠 如何移动 pch 符号的位置以使它们不与这些值重叠 library corrplot ex mat lt matrix c 1 00 0 46 0 75 1 00 0 46
  • Fluent NHibernate BinaryBlobType

    今天我正在研究 MySQL 数据库 我不知道如何将 Byte 映射到 BLOB 列 我的表看起来是这样的 CREATE TABLE images Id INT NOT NULL AUTO INCREMENT imgText VARCHAR
  • 函数数组的替代方案?

    我正在编写一个应用程序 php 它需要一个很长的列表相似但不同的功能 由一组按键调用 functions do this gt function does this do that gt function does that etc 我选择