如何使用PHPOOP将多个表单post值及其名称插入SQL数据库?

如何使用PHPOOP将多个表单post值及其名称插入SQL数据库?,php,sql,Php,Sql,首先,我是PHP OOP新手,我仍在编写代码,因此无法将完成的代码粘贴到这里,这有点像一个假设问题 1。工作流 ->呈现表单 ->用几个SQL查询中的值填充它 ->在提交时,将这些值插入到另一个数据库表中 2。表格 <form method='post'> <?php print '<tr class="oddeven">'; print '<input type="hidden"

首先,我是PHP OOP新手,我仍在编写代码,因此无法将完成的代码粘贴到这里,这有点像一个假设问题

1。工作流

->呈现表单

->用几个SQL查询中的值填充它

->在提交时,将这些值插入到另一个数据库表中

2。表格

<form method='post'>
    <?php
        print '<tr class="oddeven">';
        print '<input type="hidden" name="rowid" value="' . $row['rowid'] . '"/>';
        print '<td>' . $row['rowid'] . '</td>';
        print '<input type="hidden" name="firstname" value="' . $row['firstname'] . '"/>';
        print '<input type="hidden" name="lastname" value="' . $row['lastname'] . '"/>';
        print '<td>' . $row['firstname'] . ' ' . $row['lastname'] . '</td>';
        ... and so on ...
        print '</tr>';
?>
<input class="butAction" type="submit" name="submit2" value="<?php print $langs->trans('UpdateRecords'); ?>">
</form>
方法是

    public function insertData($rowid, $firstname, $lastname)
    {
        $this->db->begin();
        $sql  = 'INSERT ';
        $sql .= 'INTO tablename (rowid, firstname, lastname) ';
        $sql .= 'VALUES (' . $this->db->escape($rowid) . ', ' . $this->db->escape($firstname) . ', ' . $this->db->escape($lastname) . ')';
        $resql = $this->db->query($sql);
        if ($resql) {
            $this->db->commit();
        } else {
            $this->db->rollback();
            print_error($this->db);
            return -1;
        }
    }
$this->db->escape()

但是我需要插入20个值,另外还有一些额外的计算

4。我的想法

所以我想使用构造函数,所以我的代码如下:

class SomeClassName
{

    private $name;
    private $value;

    /**
    *  __Construct method
    */
    public function __construct($name=null, $value=null)
    {
        $this->name = $value;
    }

    public function insertData($name, $value)
    {
        $this->db->begin();
        $sql  = 'INSERT ';
        $sql .= 'INTO tablename (' . $this->db->escape($name) . ') ';
        $sql .= 'VALUES (' . $this->db->escape($value) . ')';
        $resql = $this->db->query($sql);
        if ($resql) {
            $this->db->commit();
        } else {
            $this->db->rollback();
            print_error($this->db);
            return -1;
        }
    }

}

$var1 = $_POST['<<<field_name_here>>>'];
$var2 = $_POST['<<<field_value_here>>>'];
$object->insertData($var1, $var2);

这篇文章将是这样的:

class SomeClassName
{

    private $name;
    private $value;

    /**
    *  __Construct method
    */
    public function __construct($name=null, $value=null)
    {
        $this->name = $value;
    }

    public function insertData($name, $value)
    {
        $this->db->begin();
        $sql  = 'INSERT ';
        $sql .= 'INTO tablename (' . $this->db->escape($name) . ') ';
        $sql .= 'VALUES (' . $this->db->escape($value) . ')';
        $resql = $this->db->query($sql);
        if ($resql) {
            $this->db->commit();
        } else {
            $this->db->rollback();
            print_error($this->db);
            return -1;
        }
    }

}

$var1 = $_POST['<<<field_name_here>>>'];
$var2 = $_POST['<<<field_value_here>>>'];
$object->insertData($var1, $var2);

$var1=$\u POST[''];
$var2=$_POST[''];
$object->insertData($var1,$var2);
我的想法是将每个表单字段
name=”“
作为
$name
传递给构造函数,并将其
value=”“
作为
$value

这样的事情能实现吗?如果是,我有几个问题:

  • 如何传递字段“name”值,因为它们将是构造函数的
    $name
    变量

  • 如何循环表单以获取所有字段名和值?使用($i=1;$i<20;$i++)的
    因为我知道eact记录数,还是有更好的方法

  • 公共函数insert data($name,$value)
    的代码将对每对名称值执行单独的查询(我想是这样吧?)。这里可以使用某种循环吗


  • 你把设计复杂化了。最重要的是,您的查询已经容易受到SQL注入的攻击。通过将其过度复杂化,只会引入更多的bug。保持简单

    创建一个简单的模型类,它将有一个方法来处理POST请求

    class UserController
    {
        public function __construct(private mysqli $db)
        {
        }
    
        public function processPost()
        {
            // instead of an array create DTO here
            $data = [
                'firstname' => filter_input(INPUT_POST, 'firstname') ?: throw new Exception('missing firstname'),
                'lastname' => filter_input(INPUT_POST, 'lastname') ?: throw new Exception('missing lastname'),
                'gender' => filter_input(INPUT_POST, 'gender') ?: null,
                // etc.
            ];
    
            $userModel = new User($this->db);
            $userModel->insert($data);
        }
    }
    
    class User
    {
        public function __construct(private mysqli $db)
        {
        }
    
        public function insert(array $data)
        {
            $stmt = $this->db->prepare('INSERT INTO users (firstname, lastname, gender) VALUES(?,?,?)');
            $stmt->bind_param(str_repeat('s', count($data)), ...$data);
            $stmt->execute();
        }
    }
    
    您可以使用调用任何其他控制器类的常规方式从应用程序中调用它

    $userController = new UserController($mysqli);
    if($_POST) {
        $userController->processPost();
    }
    

    你想得太多了。您提议的类根本不能解决这个问题,相反,它创建了另一个类(您已经注意到了)——它将每一列插入到一个单独的行中。问题的核心——你真的不需要创建这么多变量。这就是数组的用途;使用它们。将整个
    $\u POST
    传递给生成查询的方法,对列名和值使用键。。。嗯,价值观。虽然您确实不应该将视图(表单输入名称)与基础结构(DB列名)结合在一起,但这是一个不同(且冗长)的主题。另外,PDO的
    execute
    可以将一组参数作为其输入参数,因此这对您来说是一个双赢的局面。@milenmk所有PHP版本都准备了语句。您的抽象类必须准备好语句,因为这是创建SQL
    的最正确方法源代码中的所有(数百)SQL查询都是以这种方式编写的
    …然后您需要花一些时间来修复它们。安全性是一件严肃的事情,不要因为它听起来需要做很多工作而忽略它。我们不知道您的
    escape()
    函数到底做了什么,但有可能有一些方法可以破坏它,即使它们是不明确的。“修剪某些字符”不太可能是万无一失的,甚至可能在某些情况下损坏有效数据(具体取决于它所做的)。参数化是避免注入攻击和保持数据完整性的唯一100%方法。其他的都是充满希望的猜测。顺便说一句,我们也不知道你在说什么“ORM”。我得到了`意外'私有'(T_private),期望变量(T_variable)`用于
    public function.\u构造(private PDO$db)
    。其他文件中的构造函数类似于
    公共函数uu construct($db){$this->db=$db;}
    我只需将其设置为
    (PDO$ds)
    ,即可消除错误。然后我对
    processPost()
    进行了“意外”抛出“”,您必须使用旧版本的PHP。这是PHP8.0的新语法。对于PHP7.4,只需使用旧式构造函数,并用
    trigger\u error
    或类似的方法替换
    throw new exception
    ,但我必须重命名类名,因为用户已经在使用了。Get
    Uncaught TypeError:传递给BgSalaryUserController:的参数1::\uu construct()必须是PDO的实例,字符串给定
    。表单post是
    $var2=$\u post['user\u firstname.$i.']$var3=$\u POST['user\u lastname']$var4=$\u POST['user\u salary']$对象=新的BgSalaryUserController($var2、$var3、$var4)此处的代码图像:@milenmk您的构造函数获取您的依赖项,而不是数据。从过滤器输入读取数据。您的数据库连接是您的依赖项。您的第二个屏幕截图看起来像是在使用mysqli API。。。还有其他一些错误。在这种情况下,您可能希望更改代码以使用位置参数。然而,我强烈建议从mysqli升级到PDO。