使用 PDO 从 php 页面将具有更多列的表单数据插入 mysql 数据库

Posted

技术标签:

【中文标题】使用 PDO 从 php 页面将具有更多列的表单数据插入 mysql 数据库【英文标题】:insert form data with more columns into mysql database from php page using PDO 【发布时间】:2015-07-14 01:23:48 【问题描述】:

我有一个超过 25 个条目的 html 表单。

我知道如何使用 php PDO 将普通表单数据插入 mysql 数据库。但我只想知道是否有任何替代方法可以将表单条目存储到数组中并使用数组将数据插入数据库。

因为为超过 25 列编写插入语句很麻烦。

【问题讨论】:

你可以有一个带有 blob 字段的 mysql 表并将表单存储为 JSON 对象,这就是你要找的吗? 不,我有一个超过 25 列的表,在我的表单中,我为数据库表中的每个对应列都有一个条目。用 25 个列名编写插入语句很困难,因此寻找任何替代方案。 【参考方案1】:

只要您的数组具有与表相同顺序的 25 个值,您就可以使用未命名参数和惰性绑定参见 PDO info

$sql ="INSERT INTO table_name VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,)";
$stmt = $dbh->prepare($sql); 
$stmt->execute($array);

【讨论】:

【参考方案2】:

您总是可以使用 PDO 包装类,我使用下面的类来处理我的大部分 PDO 查询:

class DB 
    protected
        // Return from mysql statement
        $data = array(),
        // Used for checking whether something was added to the JSON object and remove it if the table column doens't exist
        $table_cols = array(),
        // Storing the table name we are working with
        $table = '';
    protected static
        // PDO connection to the DB
        $_conn = null,
        // The DB credentials retrieved from the ini file
        $_credentials = array ();
    private
        $_id = -1,
        $_keys = array(),
        $_values = array(),
        $_last_insert_id = -1,
        $_results = array();

    //
    //  PUBLIC FUNCTIONS
    //
    public function __construct () 
        if (self::$_conn === null) 
            self::setCredentials();
            try 
                self::$_conn = new \PDO("mysql:host=" . self::$_credentials['host'] . ";dbname=" . self::$_credentials['dbname'] , self::$_credentials['username'], self::$_credentials['password']);
             catch (\PDOException $e) 
                DebugLog::instance('DB')->error($e, 'db_connection');
            
        
    

    public function insert ($data) 
        $data = $this->checkCols($data);
        // Allows us to quickly clone data by removing the id and inserting as a new record
        if (isset($data['id'])) 
            unset($data['id']);
        
        $this->data = $data;
        $this->setDataBinding();
        $sql = "INSERT INTO `" . self::$_credentials['dbname'] . "`.`$this->table` (`" . implode('`, `', $this->_keys) . "`) VALUES (:" . implode(', :', $this->_keys) . ");";
        return $this->prepareAndExecute($sql);
    

    public function update ($data) 
        $data = $this->checkCols($data);
        if (!isset($data['id'])) 
            // Houston we have a problem, there needs to be an id to update a record
            DebugLog::instance('DB')->error("No ID set for Update: " . implode(', ', array_keys($data)), 'db_id_' . $this->table);
         else 
            // We need to unset the id because it shouldn't be in the data binding
            // But we still hold onto it for the where clause
            $id = $data['id'];
            unset($data['id']);
            $this->data = $data;

            $this->setDataBinding();

            $sql = "UPDATE `" . self::$_credentials['dbname'] . "`.`$this->table` SET ";
            $query_string = "";

            foreach ($this->_keys as $i => $key) 
                $query_string .= "`$key` = :$key, ";
            

            $query_string = trim($query_string);
            if (substr($query_string, -1) === ',') 
                $query_string = substr($query_string, 0, -1);
            

            $sql .= $query_string . " WHERE `id` = '$id'";
            return $this->prepareAndExecute($sql);
        
        return false;
    

    public function remove ($id) 
        $this->rawQuery("DELETE FROM `$this->table` WHERE `id` = '$id';");
    

    public function rawQuery ($sql) 
        try 
            $pdo = self::$_conn->query($sql);
            $pdo->setFetchMode(\PDO::FETCH_ASSOC);
         catch (\PDOException $e) 
            DebugLog::instance('DB')->error($e, 'db_query_' . $this->table);
            return array();
        
        return $pdo->fetchAll();
    

    //
    //  GETTERS
    //
    public function getColumns () 
        return $this->table_cols;
    

    public function getLastInsertID () 
        return $this->_last_insert_id;
    

    public function getRecord ($id) 
        $this->_id = $id;
        $response = $this->rawQuery("SELECT * FROM `$this->table` WHERE `id` = '$id'");
        $this->_results = $response[0];
    

    public function getResults () 
        return $this->_results;
    

    public function close () 
        $this->setDefaults();
    

    //
    //  PROTECTED FUNCTIONS
    //
    protected function initColumns () 
        $sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '" . self::$_credentials['dbname'] . "' AND TABLE_NAME = '$this->table';";
        $response = $this->rawQuery($sql);
        if (!empty($response)) 
            return $this->parseColumns($response);
        
        return array();
    

    //
    //  PRIVATE FUNCTIONS
    //
    private function setDataBinding () 
        $this->_keys = array_keys($this->data);
        foreach ($this->data as $k => $v) 
            $this->_values[':' . $k] = $v;
        
    

    private function prepareAndExecute ($sql) 
        try 
            $q = self::$_conn->prepare($sql);
            $q->setFetchMode(\PDO::FETCH_ASSOC);
            if ($q->execute($this->_values)) 
                while ($r = $q->fetch()) 
                    $this->_results[] = $r;
                
                $this->_last_insert_id = self::$_conn->lastInsertId();
                return true;
             else 
                DebugLog::instance('DB')->error('Failed to execute', 'db_' . $this->table);
            
         catch (\PDOException $e) 
            DebugLog::instance('DB')->error($e, 'db_' . $this->table);
        
        return false;
    

    private function checkCols ($array) 
        foreach ($array as $col => $val) 
            if (!in_array($col, $this->table_cols)) 
                unset($array[$col]);
            
        
        return $array;
    

    private static function setCredentials () 
            // I actually use a config file here, instead of hard coding
            self::$_credentials = array(
                'host' => '',
                'dbname' => '',
                'username' => '',
                'password' => ''
            );
    

    private function parseColumns ($cols) 
        $array = array();
        foreach ($cols as $index => $col_array) 
            $array[] = $col_array['COLUMN_NAME'];
        
        return $array;
    

    private function setDefaults () 
        $this->data = array();
        $this->table_cols = array();
        $this->table = '';
        self::$_conn = null;
        $this->_keys = array();
        $this->_values = array();
        $this->_last_insert_id = -1;
        $this->_results = array();
    

然后为每个表创建一个扩展上述类的类。例如,假设我们有一个users 表:

class UsersTable extends DB 
    public function __construct () 
        // Parent constructor creates the DB connection
        parent::__construct();
        // Now let's set the desired table based on this class
        $this->table = "users";
        // Set the table columns, for mysql column validation
        $this->table_cols = $this->initColumns();
    

用法比这么简单:

$table = new UsersTable();
$table->insert($record);

【讨论】:

以上是关于使用 PDO 从 php 页面将具有更多列的表单数据插入 mysql 数据库的主要内容,如果未能解决你的问题,请参考以下文章

从表单中检索信息以进行 PDO 查询的问题

使用 PDO 和 PHP 将表单中的数据插入 MySQL 数据库

MySQL PDO fetchAll 作为具有整数索引的数组

从 MySQL 转换后 PDO 脚本不工作

更新选择列表而不刷新 [PDO/PHP/AJAX]

JS数组到PHP并使用PDO更新MYSQL中的表