将选项字符串更改为函数

时间:2015-01-28 作者:Ahmed Saad

我正在为我的主题创建一个选项页面,在这里我可以在文本字段中插入代码,作为在我的网站中显示侧栏的条件。

假设我在文本输入中插入此值:

<input name="condition" value="is_single()">
现在,我想使用此值作为显示侧栏的条件,类似于:

<?php $condition = $options[\'condition\']; if ( $condition ) echo \'sidebar on\'; } ?>
问题是if语句中的$condition被视为字符串而不是函数。

我希望它是我在文本字段中插入的值的函数。

1 个回复
最合适的回答,由SO网友:Privateer 整理而成

要这样做,您很可能必须对提供的文本使用eval()。。。哪一个is a really bad idea.

您最好提供一个具有不同值的复选框列表,以便用户可以选择显示侧栏的项目。

例如:

<input type="checkbox" name="condition[]" value="single" /> Single Post
<input type="checkbox" name="condition[]" value="page" /> Single Page
<input type="checkbox" name="condition[]" value="blog" /> Blog
等等。

就我个人而言,我强烈建议用户尽量保持事情的简单。您可以在主题选项中使用以下内容:

在博客上显示提要栏?--无--(带有可用边栏列表的下拉框)

在单篇文章上显示提要栏?--无--

在类别存档上显示侧栏?--无--

在标记存档上显示侧栏?--无--

你想做的事可以让它发挥作用。。。但考虑到用户的平均技能,您可能会发现最好给他们一个选项列表,供他们选择,然后在绘制内容时引用这些选项。

例如,在模板上,可以执行以下操作。

$theme_options = get_option(\'my_theme_options\', get_default_theme_options() );
if ( array_key_exists( \'sidebar_positions\', $theme_options ) ) {
   if ( is_singular(\'post\') ) {
       if ( array_key_exists( \'singular\', $theme_options[\'sidebar_positions\'] ) ) {
           if ( !empty( $theme_options[\'sidebar_positions\'][\'singular\'] ) ) {
               # Draw the specified sidebar
           }
       }
   }
}
无论如何,I strongly recommend against using eval and user input 因为这是一种让人们意外破坏东西的简单方法。。。或造成严重问题。

限制他们所能做的,给他们一些干净的选择,然后把这些都解决掉,这样你的主题就会更强大。

(编辑)由于要提供真正的灵活性,可以执行以下操作之一:

1. Write a meta language for your users.

例如,您可以定义一组允许的命令。

让他们输入:single,而不是is\\u single()

或者,对于一个特定的职位:单身:12

或者,对于一些帖子:单发:12,24,25

或者,对于他们的博客:blog

如果想要将多个链接在一起,可能会输入:single:12,24,25 | blog

然后,解析输入的值:

$entered_value = stripcslashes($_POST[\'whatever\']);
您可以编写一个小的工具集来正确地确定他们输入了什么以及如何处理它。

在上述示例中,元语言具有以下特性:

如果有|,您需要在管道符号上将其分成几个部分,并且您知道每个部分都应该告诉您要显示什么类型的东西,以及可能要显示哪些特定的东西您可以使用explode(“|”,$entered\\u value)获取所有这些

对于用|分隔的每个片段,您应该有item\\u type或item\\u type:list\\u of\\ID,然后您可以按以下方式分解每个片段:(如果找到)获取项目类型和特定的ID值(用逗号分隔并去掉空格),或者只存储整个内容(如果没有找到)。

一旦完成,您就可以构建一个选项数组,注明侧栏的显示位置。对于上述示例,最终选项值可能如下所示:

array(
    \'single\' => array( 12, 24, 25 ),
    \'blog\' => true
)
然后,您可以查询自定义选项以显示侧栏。。。没有eval的噩梦。您还可以检查您的语言逻辑,并在用户出现某种错误时向用户报告。

An alternative would be to use filters:

$show\\u sidebar=apply\\u filters(\'sidebar\\u on\\u blog\',false);

$show\\u sidebar=apply\\u filters(\'sidebar\\u on\\u single,false,$post->ID);

然后,用户可以向其函数文件中添加:

add_filter(\'sidebar_on_blog\', \'show_my_sidebar_on_blog\');
function show_my_sidebar_on_blog($show) {
   return true;
}

add_filter(\'sidebar_on_single\', \'show_my_sidebar_on_single\', 10, 2);
function show_my_sidebar_on_single($show, $post_id) {
    $show_on = array(10, 23, 25);
    if ( in_array( $post_id, $show_on ) ) {
       $show = true;
    }
    return $show;
}
当然,您希望您的用户进行编程。

如果您真的必须使用eval(非常糟糕的jujuju!):

try {
    $user_input = $options[\'condition\'];
    $condition = eval("{$user_input}");
    if ( $condition ) {
        echo "sidebar on";
    }
} catch ( Exception $e ) {
    echo "<p>Exception Ahoy!</p><pre>" . print_r($e, true) . "</pre>";
}
如果需要调试,应该在运行eval之前回显用户输入,以确保它是正确的语句。在您的示例中,您省略了分号。。。因此,如果你告诉他们不要把它放进去,评估声明将变成:

$condition = eval("{$user_input};");
不客气。。。但这会带来严重的问题和令人头疼的问题。

结束