简体   繁体   English

PHP:为什么我的PDO准备语句不会将数据插入表中?

[英]PHP: Why won't my PDO prepared statement insert data into my table?

PHP 5.6.11
MySQL 5.6
CentOS 7 (with MySQL 5.6)

Note: This is not my literal code. 注意:这不是我的文字代码。 I have abstracted certain parts. 我已经摘录了某些部分。 No errors are given upon execution. 执行时不会给出错误。 No data is written to the contact table. 没有数据写入contact表。

I have a table named contact... 我有一个名为contact的表...

CREATE TABLE IF NOT EXISTS `database`.`contact`(
`contact_id` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact ID',
`firstname` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'First name.',
`lastname` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Last name.',
`email` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'E-mail address.',
`phone` VARCHAR(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Telephone number',
`country_code` VARCHAR(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Country code number',
`extension` VARCHAR(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Telephone extension',
`company` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Company affiliation.',
`address` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Street Address.',
`city` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'City.',
`state` VARCHAR(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'State.',
`zip` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Zip code.',
`country` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Country.',
`phone_type` ENUM('Cellular', 'Landline') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Telephone type',
`time_to_contact` ENUM('A.M.', 'P.M.') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Morning or Afternoon',
`contact_pref` ENUM('Email', 'Phone', 'Mail') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact preference',
`job_location` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Jobsite location',
`news_subscribed` ENUM('N', 'Y') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact subscribed to newsletter.',
`news_subs_token` VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Used when subscribing to the newsletter.',
`news_unsub_token` VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Used when unsubscribing to the newsletter.',
`message_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Time of last message.',
CONSTRAINT `contactconstr01` PRIMARY KEY (`contact_id`))
ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci COMMENT 'Contacts (external) table.';

...and I want to use this stored procedure, with embedded prepared statement, to insert records. ...并且我想使用此存储过程以及嵌入式的prepared语句来插入记录。

   CREATE DEFINER = 'blahfoobar'@'localhost' 
PROCEDURE `database`.add_contact_sp(
            IN contact_id VARCHAR(32),
            IN firstname VARCHAR(30),
            IN lastname VARCHAR(30),
            IN email VARCHAR(128),
            IN phone VARCHAR(12),
            IN country_code VARCHAR(7),
            IN extension VARCHAR(5),
            IN company VARCHAR(50),
            IN address VARCHAR(100),
            IN city VARCHAR(50),
            IN st VARCHAR(6),
            IN zip VARCHAR(10),
            IN country VARCHAR(50),
            IN phone_type VARCHAR(8),
            IN time_to_contact VARCHAR(4),
            IN contact_preference VARCHAR(5),
            IN job_location VARCHAR(100),
            IN news_subscribed VARCHAR(1),
            IN news_sub_token VARCHAR(60),
            IN news_unsub_token VARCHAR(60))
  COMMENT 'Insert new contact record.'
 LANGUAGE SQL
DETERMINISTIC
 MODIFIES SQL DATA
      SQL SECURITY DEFINER  
    BEGIN
          SET @id      = contact_id;
          SET @fName   = firstname;
          SET @lName   = lastname;
          SET @eMail   = email;
          SET @p       = phone;
          SET @cc      = country_code;
          SET @ext     = extension;
          SET @comp    = company;
          SET @addr    = address;
          SET @c       = city;
          SET @s       = st;
          SET @zCode   = zip;
          SET @coun    = country;
          SET @pType   = phone_type;
          SET @ttc     = time_to_contact;
          SET @cPref   = contact_preference;
          SET @jLoc    = job_location;
          SET @news    = news_subscribed;
          SET @nSubT   = news_subs_tokens;
          SET @nUnsubT = news_unsub_token; 

          PREPARE `insert_contact_stmt` FROM
                  'INSERT INTO `contact`
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
          EXECUTE `insert_contact_stmt` USING @id, @fName, @lName, @eMail, @p, @cc, @ext, @comp, @addr, @c, @s, @zCode, @coun, @pType, @ttc, @cPref, @jLoc, @news, @nSubT, @nUnsubT;
          DEALLOCATE PREPARE `insert_contact_stmt`;
      END//

The security settings look like.... 安全设置看起来像...。

GRANT INSERT ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost';
GRANT SELECT ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost';
GRANT UPDATE ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost';
GRANT DELETE ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost';

GRANT EXECUTE ON PROCEDURE `database`.`add_contact_sp` TO 'blahfoobar'@'localhost', 'blahblahblah'@'localhost';

...where 'blahblahblah'@'localhost' represents that actual user that makes the connection to the MySQL server during the PDO connection phase (not shown). ...其中'blahblahblah'@'localhost'表示在PDO连接阶段(未显示)与MySQL服务器建立连接的实际用户。

My PHP, a protected method of sub-class Contact (super-class Person ) looks like the following, where the $db object near the top is a wrapper object for a PDO connection. 我的PHP是子类Contact (超类Person )的一种受保护方法,如下所示,其中顶部附近的$db对象是PDO连接的包装对象。

protected function insert()
{   
    try
    {            
        $this->db->startTransaction();

        $stmt = $this->db->prepare('add_contact_sp(:contact_id, :firstname, :lastname, :email, :phone, :country_code, :extension, :company, :address, :city, :state, :zip, :country, :phone_type, :time_to_contact, :contact_pref, :job_location, :news_subscribed, :news_sub_token, :news_unsub_token');

        if($stmt instanceof PDOStatement)
        {
            //Where $stmt is passed by reference.

            $this->db->bindParam($stmt, ':contact_id', $this->id);
            $this->db->bindParam($stmt, ':firstname', $this->firstname);
            $this->db->bindParam($stmt, ':lastname', $this->lastname);
            $this->db->bindParam($stmt, ':email', $this->email);
            $this->db->bindParam($stmt, ':phone', $this->phone);
            $this->db->bindParam($stmt, ':country_code', $this->countryCode);
            $this->db->bindParam($stmt, ':extension', $this->extension);
            $this->db->bindParam($stmt, ':company', $this->company);
            $this->db->bindParam($stmt, ':address', $this->address);
            $this->db->bindParam($stmt, ':city', $this->city);
            $this->db->bindParam($stmt, ':state', $this->state);
            $this->db->bindParam($stmt, ':zip', $this->zip);
            $this->db->bindParam($stmt, ':country', $this->country);
            $this->db->bindParam($stmt, ':phone_type', $this->phoneType);     
            $this->db->bindParam($stmt, ':time_to_contact', $this->timeToContact);
            $this->db->bindParam($stmt, ':contact_pref', $this->contactPref);
            $this->db->bindParam($stmt, ':job_location', $this->jobLocation);
            $this->db->bindParam($stmt, ':news_subscribed', $this->newsSubscribed);
            $this->db->bindParam($stmt, ':news_sub_token', $this->newsSubToken);
            $this->db->bindParam($stmt, ':news_unsub_token', $this->newsUnsubToken);  

            if(!$stmt->execute())
            {
                print_r($stmt->errorInfo(), true);  //Just for debugging.
            }
            else
            {
                $this->db->commit();  
            }
        }
        else 
        {
            throw new PDOException("Failed to prepare the PDO statement.");
        }
    }
    catch(Exception $e)
    {
        $this->db->rollback();
        return false;
    }

    return true;
}

No errors. 没有错误。 No data is written to the database. 没有数据写入数据库。 Nothing. 没有。 Is it possible to use PDO transactions with MySQL stored procedures that have embedded prepared statements? 可以将PDO事务与嵌入了预准备语句的MySQL存储过程一起使用吗?

Here are my database connection options as requested. 这是我要求的数据库连接选项。

$options  = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_PERSISTENT => true,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\' COLLATE \'utf8mb4_unicode_ci\''
            ];

There are other errors in your PDO::prepare statement, but this is the first one. PDO :: prepare语句中还有其他错误,但这是第一个错误。 You are missing a parenthesis at the end of your PREPARE statement. 在PREPARE语句的末尾缺少括号。 It should look like this. 它应该看起来像这样。 The rest have to do with the order of your parameters and binding. 其余部分与参数和绑定的顺序有关。 You have twenty parameters. 您有二十个参数。 Make sure they are in the correct, corresponding order. 确保它们以正确的相应顺序排列。 Right now, they are not. 现在,他们不是。

    $stmt = $this->db->prepare('add_contact_sp(:contact_id, :firstname, :lastname, :email, :phone, :country_code, :extension, :company, :address, :city, :state, :zip, :country, :phone_type, :time_to_contact, :contact_pref, :job_location, :news_subscribed, :news_sub_token, :news_unsub_token)');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM