【问题标题】:OOP: Get method from same class to another method through anonymous functionOOP:通过匿名函数从同一类获取方法到另一个方法
【发布时间】:2018-12-24 16:21:02
【问题描述】:

我是面向对象的 PHP 新手,所以我不完全确定我的问题到底是什么,但问题是:

我创建了一个 WordPress 插件,它在由另一个插件创建的某个自定义帖子类型上添加了一堆元框。在我的主题中,我需要获取所有自定义元数据,但需要获取的内容非常多,而且通常带有某些条件等等。所以,我创建了一堆辅助函数来简化它。问题是所有这些函数的名称有点痛苦,所以我把它们放在插件的一个类中以简化事情,我的问题是我在组合它们时遇到了麻烦。不管这是否可能,希望您能帮助...

所以大多数辅助函数(现在是类方法)看起来像这样:

public function metabox_wrapper( $code ) {

    $info = get_post_meta( ID, 'blah', true);

    if ( $info ) {
        code( $info );
    }

}

然后在我的主题文件中使用:

global $Other_Plugins_Global // Created by the other plugin.
$class = new Class( $Other_Plugins_Global );

$class->metabox_wrapper( function( $info ) {
?>

    <div>
        <?php echo $info; ?>
    </div>

<?php
});

以上内容目前正在运行 - 如果存在 blah 元数据,它将显示当前帖子中的 blah 元数据。另一个插件的全局变量包含自定义帖子类型信息(以及元数据),所以我将它传递给类实例,使用类中的方法来管理所有条件和其他复杂的东西,然后使用主题文件,以便预先安排条件内容,并且能够以相同的方式在主题的其他地方使用。

但是,问题是:在某些情况下我想要类似的东西

if (
    Do this
    if (
        Also do this
    )
)

但这(以及我尝试过的所有类似方法)都不起作用:

global $Other_Plugins_Global
$class = new Class( $Other_Plugins_Global );

$class->metabox_wrapper( function( $info ) {
?>

    <div>
        <?php echo $info; ?>
    </div>

    <?php
    $class->other_metabox_wrapper( function( $stuff ) {
    ?>

        <div>
            <?php echo $stuff; ?>
        </div>

    <?php
    });

});

所以我的问题是......有没有办法可以在彼此内部使用这些包装函数?我尝试将它们设置为静态并在主题中使用::,我尝试了一些花哨的可变体操,但它不起作用,如果有的话会很难看,我几乎养了一个恶魔,试图打电话给方法内部的全局变量......所以此时我什至不确定谷歌是什么。

显然,对于这个特定的示例,我可以只使用 if(){},但条件逻辑通常有多个条件和其他半复杂的东西,所以保持独立并能够在周围的多个地方使用会很有帮助主题。

我会说,如果这是一个愚蠢的问题,并且您知道一种完全不同且更优雅的方式来完成我所描述的内容,那么我会全神贯注。

非常感谢您的帮助。

【问题讨论】:

  • 第一个 sn-p 中的变量 $code 未使用,但调用了函数 code()。错字?

标签: php class oop methods


【解决方案1】:

首先您必须阅读一些编码标准文章 1.https://www.tutorialspoint.com/php/php_coding_standard.htm

  1. 尝试将PHP代码和HTML分开;使用 Twig 代替 PHP 让生活变得更轻松 https://aristath.github.io/blog/using-twig-in-wordpress

  2. 当您有更多帮助(挂钩)函数时,最好将它们分组到一个类中,或者创建一个 Helper 目录结构并为每个范围创建一个文件。 (例如:修剪字符串,调整图像大小创建不同的文件)

  3. 创建 Helpers 后尽量不要将 HTML 放入其中;助手假设返回一个值(布尔值)。
    例如 showCampaign() => 将返回 True;
    HTML 页面/ TWIG 页面 {{ if(showCampaign()) }} //HTML代码在这里 {{ endif }}

  4. 如果您有太多 if/else 语句需要重构,请检查上面的链接或其他示例:https://carlalexander.ca/mastering-php-conditionals/

  5. 编码愉快!

【讨论】:

  • 感谢您提供有趣的文章,但对我的问题并没有特别的帮助,即我正在尝试干燥并简化使用条件逻辑在主题中显示帖子元数据.
  • 欢迎,事情是当你完成任务并且代码正在做应该输出的事情时。下一步是改进代码。遵循最佳实践: 1. 将 PHP 与 HTML 分离 2. 使用 DRY、KISS、重构 IF/ELSE 语句,将函数分组到类中,甚至在项目中创建更好的树结构以保持干净和易于使用。
【解决方案2】:

问题不在于 OOP 领域,而在于函数和函数范围。您会看到,当您创建anonymous function 时,它有自己的范围——可访问的变量范围。在大多数语言中,匿名函数包含了它创建的作用域,创建了一个closure——这意味着它可以访问父作用域中所有变量的副本。在 PHP 中并非如此,因此为了从匿名函数中访问 $class 变量,您应该使用 use: $class-&gt;metabox_wrapper(function($info) use ($class) {

另一种方法是使用Closure::bind() 将上下文绑定到匿名函数:

public function metabox_wrapper($code) {
    $info = get_post_meta(ID, 'blah', true);

    if ($info) {
        $code = Closure::bind($code, $this);
        $code($info);
    }
}

然后你可以在匿名函数中使用$this

$class->metabox_wrapper(function($info) {
?>
    <div>
        <?php echo $info; ?>
    </div>

    <?php
    $this->other_metabox_wrapper(function($stuff) {
    ?>
        <div>
            <?php echo $stuff; ?>
        </div>
    <?php
    });
});

但说实话,我同意@CrisanLucian。以这种方式将代码与 HTML 混合并不是最好的编程方式。

【讨论】:

  • 这太好了,非常感谢!我同意这不是我想要公开使用的东西,但这永远不会在我自己的项目之外发布或使用。因此,在这种情况下,它非常规的事实并不会打扰我 - 只要我理解它并且它让我的生活更轻松,我就可以将它用于我的计划。话虽如此,您反对是因为它不是最佳实践还是因为它不安全或不安全?我不介意为了我自己而使用一些不寻常的东西,但显然我也不想妥协。
  • @Shoelaced,我自己不是安全专家,所以我没有能力告诉你它是否安全。据我了解,它足够安全。问题是它难以阅读且难以修改。我不知道 WordPress,所以不知道它的生态系统。如果这种编码风格在 WordPress 中是惯用的,那么,好吧,“在罗马,像罗马人那样做”)
猜你喜欢
  • 1970-01-01
  • 2018-10-23
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
相关资源
最近更新 更多