【问题标题】:Effective form processing using php使用php进行有效的表单处理
【发布时间】:2018-02-07 21:25:00
【问题描述】:

我正在处理某个项目,我想在多个模板中处理来自表单的请求。问题是如何在处理脚本中调用适当的函数。虽然,我已经编码了一段时间,但我仍然想不出比在隐藏字段中使用变量更好的方法:

if ($_POST['somehiddenfield'] == 1) {
   some_function_1();//doesnt matter if its a function or a method
}

if ($_POST['somehiddenfield'] == 2) {
   $mainclass->somemethod();
}
//goes on indefinitely

我还想将所有内容保存在一个处理程序文件中,在该文件中调用我的主类。那么有没有比使用if ... else更有效的方法呢?

【问题讨论】:

  • 怎么样发送更多的阅读值(仍然在隐藏字段中),您可以从中编写方法名称?为每个表单指定一个特定的名称。
  • 虽然您的问题与 AJAX 无关,但 post 可能与您的问题有关。
  • 或者有一个arrray(array("type"=>1, "method"=>"personalForm"), array(..))
  • IMO 使用隐藏输入非常好。这几乎就是他们的目的。但是,我通常不使用它们来拆分 PHP 端的函数。我通常做的是在javascript中设置一个全局变量,从而确定通过ajax调用哪个函数。 (因此,根据我要调用的函数更改 URL 请求) - 如果可以,另一种方法是将其作为函数参数发送。我倾向于将整数作为参数(url/class/function/parameter)发送,但你需要为此设置路由。
  • 如果您打算使用 OOP,我建议您开始研究诸如 LumenSlimFramework 等微框架。 IMO 框架将通过控制器(您正在寻找的)、视图和模型来保持您的代码干净、有条理和可维护。

标签: php ajax oop


【解决方案1】:

我会做以下事情:

仍然有一个隐藏字段,但让它包含类似于表单名称的内容

<input type="hidden" name="formName" value="post">

然后你可以在消费 php 脚本中做类似的事情:

<?php
// whatever class you use... this is just a simple dummy
class FormsProcessor {
      public function post($params) {
          echo "processing post form";
      }
}

$formName = "post";  // would be $formName = filter_input(INPUT_POST, $_POST['formName'],FILTER_SANITIZE_STRING,FILTER_FLAG_STRIP_HIGH);
// BUT BE SURE TO SANITIZE THE INPUT!!!

$params = [];  // dummy
$formsProcessor = new FormsProcessor();
                 // here's the trick.
$formsProcessor->{$formName}($params);
// to be even safer you could check first if this method_exists() 
// and/or if it's in a list of allowed methods.

请注意,此类中不得有任何其他用户不应调用的方法。你可以通过真正组合两部分的方法名称来解决这个问题:

$methodName = $formName."Processor";
//....
$formsProcessor->{$methodName}();`

【讨论】:

  • 但一定要清理输入!!!”这部分需要更大胆和更大:)
  • @IncredibleHat 我正在使用 PDO,但这个建议总是很重要
  • 该部分将变量解析为方法名称。 $formsProcessor-&gt;$formName 不起作用。就像您在字符串中所做的一样 "footext {$bar[2]} moretext";
  • 这是文档:php.net/manual/de/…
  • 请注意,此类中不得有任何其他用户不应调用的方法。你可以通过真正组合两部分的方法名称来解决这个问题:$methodName = $formName."Processor"; -> $formsProcessor->{$methodName}();`
【解决方案2】:

我会保留一个包含所有可能选项的硬编码 key=>value 数组。传递隐藏的输入字段,检查您的帖子值和硬编码选项的键之间是否有任何交集,并将任何匹配的值调用为函数。

$map = [
    'yourHiddenField' => 'myFunctionName',
    'anotherHiddenField' => 'myOtherFunctionName',
    'yourOtherHiddenField' => 'yetAnotherfunctionName',
];

$intersection = array_intersect(array_keys($map), array_keys($_POST));

foreach ($intersection as $key) {
    $this->{$map[$key])();
}

此代码未经测试。

编辑: 请注意允许运行任何输入而不预定义应允许运行的功能。

即使经过消毒也可能有多危险的示例:

class Test {
    public $i = 1;

    function __construct(){
        $this->i++;
    }
}

$formVariable = '__construct';

$t = new Test();

$t->{$formVariable}();

echo $t->i;

【讨论】:

  • 一个有趣的方法。确实,您的示例表明不清理数据是多么危险,谢谢!
  • 很高兴我能帮上忙。永远不要让用户定义确切的函数来运行 - 总是映射事物。
  • @gonzie 我们通常不允许我们的用户通过路由和.htaccess 运行功能吗?或者你会认为这不同吗? :P
  • @Babydead 用户运行您希望他们运行的功能。所有路由通常都是预定义的,无论如何它们不是,它们仍然不会操纵文件中的代码。路由和允许代码注入之间存在巨大差异。
  • @gonzie 只是想确保有所不同并且我的想法是有道理的,哈哈哈。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
相关资源
最近更新 更多