在这种情况下使用val()可以吗?

时间:2011-10-31 作者:Andy James

我正在尝试使用“get\\u template\\u part()”包含用户输入。这些包含添加在主题选项中,例如用户输入。

get_template_part(\'content/block\', \'branding\');
get_template_part(\'content/block\', \'footer\');
我需要以php的形式执行这段代码,并为add\\u before\\u content()提供一个自定义挂钩,该挂钩在内容和侧栏之前运行。

在layouts类中,我有一个方法检查用户输入,然后使用该方法使用eval()添加包含

function add_before_content() {
    global $options;
    $string = "get_template_part(\'content/block\', \'branding\');";
    return eval($string);
}

add_action(\'before_content\', \'add_before_content\');
这非常有效,但是当使用eval()时,我会感到紧张,尤其是当它涉及用户输入的内容时。

我在这个场景中的想法是,应该避免使用它,因为它允许用户输入任何php代码并将其执行。

但是,只能通过管理员登录进行访问。

实际上,我已经实现了一个不同的解决方案,但我想把这个问题提出来,因为得到一些反馈会很好。

在这种情况下,eval()是个坏主意吗?

进一步澄清,我试图达到与打开索引相同的结果。主题和添加的php文件get_template_part() 包含模板文件。例如:

<?php get_template_part(\'content/block\', \'header\'); ?>

但允许用户从主题选项执行此操作,而无需打开主题文件。

文件的内容其实并不重要,它只是一个普通的php include,应该在调用时包含并运行。

在我的主题选项中,我有一个编辑器元素(extended textarea),用于一些功能,因此可以从主题选项将代码添加到主题中,而无需用户打开主题文件。

这对于我迄今为止添加的html非常有效。该值存储在数据库中,当其在主题中回显时,它会回显html,没有问题。

然而,当我想允许用户从主题编辑器中添加包含的php时,我就陷入了困境。

用户可以在两个位置添加这些Include。在内容的上面和下面都有挂钩,这就是我使用它们的原因。

下面是编辑器的屏幕截图,其中定义了includes。

http://cl.ly/3n3r3H381g1U1a2t3T3g

我需要的是包含文件的品牌和标题,就像我打开了索引一样。php文件,并在文件中手动输入get\\u template\\u部分,而不是编辑器。

只需使用您解释的方式将值作为字符串输出到页面上,如下所示

http://cl.ly/3I251I0B282i0c0E0U2j

而不是实际包含那些模板文件。

使用eval()意味着编辑器的保存值(一个字符串)将被计算为php,并添加include,就像我在索引中添加它一样。php,这就是它工作的原因,也是我唯一能理解它的方法。

我希望这能让事情变得更清楚。

感谢您的耐心:)

我在这里谈论的这个特定功能的概念是我唯一一次尝试添加php的地方,后来我尝试了另一种方法,但我发布了这个关于eval()的问题,因为我想证实我的想法。

这是一个父主题,第一次安装时只有一个内容区域和侧栏……上面或下面都没有。就像一块“干净的石板”在创建网站时开始。该主题有一个称为“积木生成器”的东西,它允许用户定义并向其网站添加/删除“积木”,然后定义要在这些积木中显示的内容。他们可以添加一个名为“品牌”的块

构建块就像网站上的任何内容“部分”。徽标区域、导航区域、页脚搁板、工具栏等。

构建块概念取自我们开发的Joomla模板框架,该框架的核心是构建块。

www.getmorp。组织机构

定义块后,可以通过4种方式之一将其设置为输出。

小部件(如果设置为小部件,则会创建一个具有块名称的新小部件pos)

  • 特色贴子(可以将贴子页面上的任何贴子特色化到块或从设置的类别中提取并显示为网格、旋转木马、滑块等)
  • 自定义html(它们可以输入任何html和一些流行元素的[标记],如[徽标][网站名称]等主题。是的,这也可以使用小部件来完成,因此他们可以将小部件设置为输出,并将html放入小部件中。。同样的结果,这只是简单了一点,但可以根据用户的喜好进行选择块创建是完全自动化的,添加新块时,将创建一个包含所有相关选项的新包含,并使用ajax动态创建一个主题选项页面。

    显然,如果不在某个地方实际调用主题中的块,这将不起作用……这是唯一的手动步骤,也是我最初问题的全部要点显露出来的地方。

    任何用户都可以轻松地打开索引。php或更好的方法创建子主题并添加索引。php并添加代码来调用该块

    <?php get_template_part(\'content/block\', \'header\'); ?>

    这甚至是文档中解释的方式,甚至使用块名生成代码段,他们只需单击以复制它。给出了如何添加块的说明。。这是他们唯一需要做的事情。确实很简单。

    然而,在使用封闭的用户团队进行alpha测试时,一些人问是否可以不打开主题文件来添加块include…因此我的问题是。

    注意:构建块是可选的。。用户不必使用它们,他们可以像使用其他主题一样使用该主题,但对于许多用户来说,这将使他们的网站建设和修改变得非常困难!!更简单。

    这意味着不需要定义70个小部件位置,以备用户需要。我们的方法是可伸缩的,它只从边栏小部件的位置开始。

    由于主题是以slate为基础开发的,因此可以根据需要通过添加所需的块来添加无限的小部件位置。

  • 3 个回复
    最合适的回答,由SO网友:EAMann 整理而成

    我知道你想做什么。。。我一点也不喜欢。您在主题选项方面包含的内容太多了,特别是如果您在选项屏幕上允许自由格式的PHP代码。

    为什么这是个坏主意整个WordPress项目的口号是;决定,而不是选择"E;事实上,一个主题的选项越多,管理起来就越混乱。如果你真的需要有那么多的定制可用,构建一个父主题,并让人们在此基础上构建自定义子主题。

    思考创世记或论文。非常强大的主题,通过定制的子主题提供了多种设计选项。

    如果你坚持,下面是你可以做的,你说你想给用户一个选项,让他们在不直接编辑主题文件的情况下,在网站中排列显示块:

    在我的主题选项中,我有一个编辑器元素(extended textarea),用于一些功能,因此可以从主题选项将代码添加到主题中,而无需用户打开主题文件。

    这听起来就像WordPress:widgets中已经存在的另一个系统。

    小部件只是一个预定义的内容模板,您可以将其拖放到WordPress中widgetized表面的任何位置。有些人只有一个侧栏可以容纳小部件。其他人在他们的主题中有几个widgetized区域(我见过至少一个70 different widget-ready locations!).

    似乎您已经定义了内容块(模板部分)。我建议您做以下两件事之一:

    1. Have the users edit the files directly. 您已经让他们在选项面板上编写PHP了。对他们来说,直接编辑PHP并不是一个很大的步骤
    2. Widgetize your theme. 这些不一定是典型的WordPress小部件。。。但您的自定义模板部分是预定义的内容块,类似于小部件的方式。不要重新发明轮子。如果您希望人们将其放置在不同的位置,请为他们提供一个这样做的界面
    jQuery使drag and drop 从一个地区到另一个地区的项目。然后您可以将排序保存在选项表中,并直接调用。。。不使用eval().

    SO网友:Chip Bennett

    我看不出有什么理由使用eval() 在这种情况下。

    我需要以php的形式执行这段代码,并为add\\u before\\u content()提供一个自定义挂钩,该挂钩在内容和侧栏之前运行。

    因此,您为用户提供了文本输入或文本区域,并且需要在模板中输出该内容。您希望在自定义挂钩上执行此操作。到目前为止一切都很好。这里是您出错的地方:

    在layouts类中,我有一个方法检查用户输入,然后使用该方法使用eval()添加包含

    function add_before_content() {
        global $options;
        $string = "get_template_part(\'content/block\', \'branding\');";
        return eval($string);
    }
    
    add\\u action(\'before\\u content\',\'add\\u before\\u content\');

    这有什么意义?

    第一:为什么要将用户输入写入PHP文件,而不是适当地将其存储在数据库中?

    第二:您已经在自定义挂钩回调中;为什么不直接从回调输出用户输入?

    假设您已调用此选项content_branding. 尝试以下操作:

    function add_before_content() {
        global $options;
        // Sanitize, for safety
        $content_branding = wp_kses_post( $options[\'content_branding\'] );
        // Echo (or return) the result
        echo $content_branding;
    }
    
    add_action(\'before_content\', \'add_before_content\');
    
    我错过了什么?

    EDIT

    The reason I say the contents are not important is because it can be anything and they all differ. Some are just outputting a widget positions, others featured posts. But the same scenario would be true if the file just had Whatever the php is inside the included file is, it should just run as if its included normally.

    基于这一澄清,我将重申(并支持)Eric Mann的建议,即不要使用当前的方法,而是使用动态侧栏和自定义小部件。

    SO网友:unity100

    您可以将整个代码放入一个数组中,如下所示:

    $safe= array(
    
        \'get_template_part(\\\'content/block\\\', \\\'branding\\\');\',
        \'get_template_part(\\\'content/block\\\', \\\'footer\\\');\'
    );
    
    然后在函数中引入以下检查,以确保除了您已经列出的代码之外,没有其他类型的代码可以发送到eval:

    function add_before_content() {
        global $options;
        global $safe;
        $string = (this comes from user)
        if(in_array($string,$safe))
        {
            return eval($string);
        }
    }
    
    add_action(\'before_content\', \'add_before_content\');
    
    或者,只需修改函数并对照可以包含的不同类型的模板进行检查:

    $safe= array(
    
        \'branding\',
        \'footer\',
    );
    
    function add_before_content() {
        global $options;
        global $safe;
        $string = (this comes from user)
        if(in_array($string,$safe))
        {
            return eval("get_template_part(\'content/block\', \'".$string."\');");
        }
    }
    
    add_action(\'before_content\', \'add_before_content\');
    
    无论采用哪种方式,用户都不可能发送您允许的内容以外的任何内容,因此这是安全的。

    我更喜欢后者,因为它更干净。

    结束

    相关推荐

    Create a blank test.php

    有时有必要找出CSS错误或其他什么,如果您有一个最小的测试页面,只需插入要测试的特定代码,那就太好了。我如何创建这样一个空测试。php?我只能找到this. 但是,这样做只会创建与页面样式相同的页面。php一号,不是吗?我想我需要在我的功能中加入一些东西。php告诉Wordpress它应该为测试创建一个新模板。php?我该怎么做?提前非常感谢!:)