簡體   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)

注意:這不是我的文字代碼。 我已經摘錄了某些部分。 執行時不會給出錯誤。 沒有數據寫入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.';

...並且我想使用此存儲過程以及嵌入式的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//

安全設置看起來像...。

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';

...其中'blahblahblah'@'localhost'表示在PDO連接階段(未顯示)與MySQL服務器建立連接的實際用戶。

我的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;
}

沒有錯誤。 沒有數據寫入數據庫。 沒有。 可以將PDO事務與嵌入了預准備語句的MySQL存儲過程一起使用嗎?

這是我要求的數據庫連接選項。

$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\''
            ];

PDO :: prepare語句中還有其他錯誤,但這是第一個錯誤。 在PREPARE語句的末尾缺少括號。 它應該看起來像這樣。 其余部分與參數和綁定的順序有關。 您有二十個參數。 確保它們以正確的相應順序排列。 現在,他們不是。

    $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