我在尝试插入和反对数据库时遇到问题。使用var_dump,似乎将ProductID强制转换为值为0的字符串。
var_dump显示:
object(Products)#1 (9) { ["ProductID"]=> string(1) "0" ["ProductTypeID"]=> int(1) ["Status"]=> int(1) ["Name"]=> string(1) "1" ["imgSrc"]=> string(1) "1" ["Price"]=> float(1) ["Veggie"]=> NULL ["Heated"]=> bool(true) ["Description"]=> string(1) "1" }
我相信它应该显示:
object(Products)#1 (9) { ["ProductID"]=> int(0) ["ProductTypeID"]=> int(1) ["Status"]=> int(1) ["Name"]=> string(1) "1" ["imgSrc"]=> string(1) "1" ["Price"]=> float(1) ["Veggie"]=> NULL ["Heated"]=> bool(true) ["Description"]=> string(1) "1" }
有人会介意看看我出错了吗?
<?php
function addBagel() {
$results = array();
$results['pageTitle'] = "New Bagel";
$results['formAction'] = "addBagel";
$results['formTitle'] = "Add a Product,";
if ( isset( $_POST['saveChanges'] ) ) {
// User has posted the object edit form: save the new product
$product = new Products;
$product->storeFormValues( $_POST );
//Calls the inset function
$product->insert();
var_dump($product);
header( "Location: admin.php?&status=changesSaved" );
} elseif ( isset( $_POST['cancel'] ) ) {
// User has cancelled their edits: return to the product list
header( "Location: admin.php?action=listArticles" );
} else {
// User has not posted the Product save form yet: display the form
$results['product'] = new Products;
$data = Products::getList();
require( TEMPLATE_PATH . "/admin/editBagels.php" );
}
}
?>
And my class;
<?php
class Products
{
// Properties
/**
* @var int the id
*/
public $ProductID = null;
/**
* @var int product ID
*/
public $ProductTypeID = null;
/**
* @var int the status of availability
*/
public $Status = null;
/**
* @var string The name of the item
*/
public $Name = null;
/**
* @var string src to associated image
*/
public $imgSrc = null;
/**
* @var float src to associated image
*/
public $Price = null;
/**
* @var string src to associated image
*/
public $Veggie = null;
/**
* @var string src to associated image
*/
public $Heated = null;
/**
* Sets the object's properties using the values in the supplied array
*
* @param assoc The property values
*/
public function __construct( $data=array() ) {
if ( isset( $data['ProductID'] ) ) $this->ProductID = (int) $data['ProductID'];
if ( isset( $data['ProductTypeID'] ) ) $this->ProductTypeID = (int) $data['ProductTypeID'];
if ( isset( $data['Status'] ) ) $this->Status = (int) $data['Status'];
if ( isset( $data['Name'] ) ) $this->Name = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['Name'] );
if ( isset( $data['Description'] ) ) $this->Description = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['Description'] );
if ( isset( $data['imgSrc'] ) ) $this->imgSrc = $data['imgSrc'];
if ( isset( $data['Price'] ) ) $this->Price = (float) $data['Price'];
if ( isset( $data['Veggie'] ) ) $this->Veggie = (bool) $data['Veggie'];
if ( isset( $data['Heated'] ) ) $this->Heated = (bool) $data['Heated'];
}
/**
* Sets the object's properties using the edit form post values in the supplied array
*
* @param assoc The form post values
*/
public function storeFormValues ( $params ) {
// Store all the parameters
$this->__construct( $params );
}
/**
* Inserts the current Product object into the database, and sets its ID property.
*/
public function insert() {
// Does the Product object already have an ID?
if ( !is_null( $this->ProductID ) ) trigger_error ( "Product::insert(): Attempt to insert a Product object that already has its ID property set (to $this->ProductID).", E_USER_ERROR );
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
// Insert the Article
$sql = "INSERT INTO Products ( ProductTypeID, Status, Name, Description, imgSrc, Price, Veggie, Heated)
VALUES (:ProductTypeID, :Status, :Name, :Description, :imgSrc, :Price, :Veggie, :Heated)";
$st = $conn->prepare ( $sql );
$st->bindValue( ":ProductTypeID", $this->ProductTypeID, PDO::PARAM_INT );
$st->bindValue( ":Status", $this->Status, PDO::PARAM_INT );
$st->bindValue( ":Name", $this->Name, PDO::PARAM_STR );
$st->bindValue( ":Description", $this->Description, PDO::PARAM_STR );
$st->bindValue( ":imgSrc", $this->imgSrc, PDO::PARAM_STR );
$st->bindValue( ":Price", $this->Price, PDO::PARAM_STR );
$st->bindValue( ":Veggie", $this->Veggie, PDO::PARAM_STR );
$st->bindValue( ":Heated", $this->Heated, PDO::PARAM_STR );
$st->execute();
$this->ProductID = $conn->lastInsertId();
print_r( $this );
$conn = null;
}
?>
Products
CREATE TABLE `Products` (
`ProductID` int(11) NOT NULL,
`ProductTypeID` int(11) NOT NULL,
`Status` tinyint(1) NOT NULL,
`Name` varchar(80) NOT NULL,
`Description` varchar(150) NOT NULL,
`imgSrc` varchar(150) NOT NULL,
`Price` float NOT NULL,
`Veggie` tinyint(1) NOT NULL,
`Heated` tinyint(1) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
答案 0 :(得分:1)
PDO::lastInsertId()
返回一个字符串。这是因为有些数据库不一定要使用整数,postgres中的序列也可以是字符串。如果重要的话,使用(int)$conn->lastInsertId();
投射它。我希望你设置PDO
以便在错误上抛出异常。
答案 1 :(得分:1)
为$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD )
设置属性,如下所示也可以。 int类型不会转换为字符串。
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES , false);
PDO::ATTR_EMULATE_PREPARES
启用或禁用对准备好的语句的仿真。一些驱动程序不支持本机准备的语句或对其的支持有限。使用此设置可以强制PDO始终模拟预准备的语句(如果驱动程序支持TRUE和模拟的预准备),或者尝试使用本机的预准备语句(如果为FALSE)。如果驱动程序无法成功准备当前查询,它将始终退回到模拟准备好的语句。需要布尔值。
emulate prepared statements
将自动将int转换为字符串。原因可能是被接受的回答者说的It's because some databases do not necessarily have to use integers, sequences in postgres can be also strings.