PDA

View Full Version : سوال: عمل ثبت به وسیله ی pdo



soroush.r70
شنبه 02 آذر 1392, 09:44 صبح
چرا وقتی به وسیله ی pdo می خوام اطلاعات رو ثبت کنم نمی تونم فیلدی رو خالی بذارم و بقیه رو ثبت کنم یعنی می گه حتما باید همه پر باشه دلیلش چیه...؟


$class->query("INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL ,:ip,:active)");
$class->bind(':ip',$ip);
$class->bind(':active',$active);
$class->execute();


مثلا من در کد بالا فقط ip رو پر می کنم بدون اینکه active پر باشه خطای زیر رو می ده


Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'active' cannot be null' in F:\xampp\htdocs\baz\bzadmin\inc\class.php:67 Stack trace: #0 F:\xampp\htdocs\baz\bzadmin\inc\class.php(67): PDOStatement->execute() #1 F:\xampp\htdocs\baz\bzadmin\ip.php(45): content->execute() #2 {main} thrown in F:\xampp\htdocs\baz\bzadmin\inc\class.php on line 67

Veteran
شنبه 02 آذر 1392, 10:18 صبح
اینجارو ببینید
(http://www.php.net/manual/en/pdo.prepared-statements.php)

soroush.r70
شنبه 02 آذر 1392, 19:25 عصر
بازم که نشد دستوراتی که من در بالا نوشتم که مشکلی نداره چرا جواب نمی ده...؟

2undercover
شنبه 02 آذر 1392, 21:15 عصر
مطمئنید که توی پایگاه داده برای ستون active قابلیت Null بودن رو فعال کردید؟!

soroush.r70
شنبه 02 آذر 1392, 21:50 عصر
الان null کردم درست شد

فقط یک سوال تمام فیلدهای جدولم null برابر با no هست یعنی باید همه رو yes کنم تا اینطوری نشه پس چرا تا زمانی که از pdo استفاده نمی کردم اینطوری نمی شد و مشکلی نبود...؟

2undercover
یک شنبه 03 آذر 1392, 14:04 عصر
به این دلیل که وقتی توی PDO شما پارامتر ها رو به عنوان Null مقدار دهی کنید توسط متد bind توی کوئری هم مقدار NULL جایگزین میشه که با وقتی که با استفاده از تابع mysql_query یک فیلد رو می خواید خالی مقدار دهی کنید از عبارت '' استفاده می کنید متفاوته. یعنی این دو کوئری زیر متفاوت هستند:

INSERT INTO `table`(`id`, `notnull`) VALUES (NULL, NULL)
INSERT INTO `table`(`id`, `notnull`) VALUES ('', '')

که اولی خطا میده چون ستون notnull نمی تونه مقدار NULL بپذیره. اما توی کوئری دوم مقدار ستون notnull برابر با یک رشته خالی میشه!

پس اگه می خواید با PDO مقدار یک ستون رو خالی قرار بدید اینجوری عمل کنید:


$query->bind(':empty', '');

soroush.r70
یک شنبه 03 آذر 1392, 14:48 عصر
ببین من در موقع insert کردن این مشکلو دارم در کد زیر من update می کنم مشکل تدارم ولی وقتی insert می کنم و فیلد ip رو پر می کنم و active رو خالی می ذارم این مشکلو دارم دلیلش چیه...؟


if(!empty($ip))
{
if(!empty($edit))
{
global $active;
$class=new content;
$class->query("UPDATE `tbl_ip` SET
`ip` = :ip,
`active` = :active
where `id`=:edit ");
$class->bind(':ip',$ip);
$class->bind(':active',$active);
$class->bind(':edit',$edit);
$class->execute();

echo'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script >alert(" ویرایش صورت گرفت.");</script>
<meta http-equiv="refresh" content="1;url='.URL.'ip.php" />';
die();
}
else
{
global $active;
$class->query("INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL ,:ip,:active)");
$class->bind(':ip',$ip);
$class->bind(':active',$active);
$class->execute();

echo'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script >alert(" رکورد جدید افزوده شد.");</script>
<meta http-equiv="refresh" content="1;url='.URL.'ip.php" />';
die();
}
}

2undercover
یک شنبه 03 آذر 1392, 16:00 عصر
خوب شما کوئری مربوط به INSERT رو اینجوری تغییر بده و قسمتی که :active رو bind کردی بردار:

INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL ,:ip,'')

soroush.r70
یک شنبه 03 آذر 1392, 16:21 عصر
خوب اگه بخوایم active پر باشه چی شما اینکارو کردی که همش active باید خالی درج بشه

2undercover
یک شنبه 03 آذر 1392, 20:47 عصر
خوب اگه بخوایم active پر باشه چی شما اینکارو کردی که همش active باید خالی درج بشه

خوب پس اگه می خواید مقدار active خالی باشه متغیر $active رو یک رشته خالی در نظر بگیر به طور پیش فرض نه مقدار NULL

soroush.r70
یک شنبه 03 آذر 1392, 21:24 عصر
یهنی چی به چه صورت...؟

2undercover
دوشنبه 04 آذر 1392, 14:02 عصر
الان شما میگی وقتی مقدار متغیر active رو خالی قرار میدی اون خطا بوجود میاد. خب کی متغیر active خالی هست (NULL هست) همون موقع به جای اینکه خالی بزاریش اون رو برابر با یک رشته ی (STRING) خالی قرار بده!

soroush.r70
دوشنبه 04 آذر 1392, 17:52 عصر
می شه یه مثال بزنی ممنون چطور می شه که من وقتی دارم به صورت زیر ثبت می کنم


global $active;
$class->query("INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL ,:ip,:active)");
$class->bind(':ip',$ip);
$class->bind(':active',$active);
$class->execute();

بیام و یک رشته رو خالی بفرستم اگه active خالی بود

2undercover
دوشنبه 04 آذر 1392, 21:32 عصر
$class->bind($query, !is_null($active) ? $active : '');

soroush.r70
دوشنبه 04 آذر 1392, 23:43 عصر
$class->bind($query, !is_null($active) ? $active : '');




ممنون و یه سوال دیگه تابع bind باید به چه صورت باشه تا دستوری که شما نوشتی جواب بده

تابع bind من :


public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}

2undercover
سه شنبه 05 آذر 1392, 14:42 عصر
ممنون و یه سوال دیگه تابع bind باید به چه صورت باشه تا دستوری که شما نوشتی جواب بده

تابع bind من :


public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}



به همین صورت درست هست!

soroush.r70
سه شنبه 05 آذر 1392, 21:42 عصر
الان اومدم اینکارو کردم بازم خطا داده


$query=$class->query("INSERT INTO `tbl_slider`
(`id` ,`title`,`text`,`pic`,`group`)
VALUES (NULL,?,?,?,?)");

$class->bind($query, !is_null($title) ? $title : '');
$class->bind($query, !is_null($text) ? $text : '');
$class->bind($query, !is_null($dir) ? $dir : '');
$class->bind($query, !is_null($group) ? $group : '');
$class->execute();



خطا :



Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: Columns/Parameters are 1-based' in F:\xampp\htdocs\baz\bzadmin\inc\class.php:61 Stack trace: #0 F:\xampp\htdocs\baz\bzadmin\inc\class.php(61): PDOStatement->bindValue(0, 'sdcsdcsdcdddddd...', 2) #1 F:\xampp\htdocs\baz\bzadmin\atelie.php(101): content->bind(NULL, 'sdcsdcsdcdddddd...') #2 {main} thrown in F:\xampp\htdocs\baz\bzadmin\inc\class.php on line 61

2undercover
چهارشنبه 06 آذر 1392, 05:37 صبح
خوب اون متد bind که نوشتید برای پارامتر های نام دار درست کار می کنه و برای اینکه پارامتر ها رو بر اساس عدد بخواید جایگزین کنید باید متد تغییر داده بشه!

soroush.r70
چهارشنبه 06 آذر 1392, 18:32 عصر
به چه صورت باید تغییر کنه...؟

2undercover
چهارشنبه 06 آذر 1392, 19:50 عصر
الان این متغیر $class چی هستش؟! اگه یک کلاس هست که خودتون نوشتید بزارید اینجا تا بهتر بشه راهنمایی کرد!

اگر هم که با پارامتر های نام دار درست کار می کنه کافیه برای آرگومان اول عدد اون پارامتر و بعد هم مقدار رو به متد bind بدید! یعنی اینجوری:



$class->bind(1, !is_null($title) ? $title : '');

soroush.r70
چهارشنبه 06 آذر 1392, 20:03 عصر
نه کلاسیه که خودم نوشتم

class.php


<?php
class content
{
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;

private $stmt;
private $dbh;
private $error;

public function __construct(){
// Set DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
);
// Create a new PDO instanace
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
/*** close the database connection ***/
//$this->dbh = null;

}
// Catch any errors
catch(PDOException $e){
$this->error = $e->getMessage();
}
}





// query
public function query($query){
$this->stmt = $this->dbh->prepare($query);
}


public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}



public function execute(){
return $this->stmt->execute();
}




public function resultset(){
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}





public function single(){
$this->execute();
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}




public function rowCount(){
return $this->stmt->rowCount();
}



public function lastInsertId(){
return $this->dbh->lastInsertId();
}




public function beginTransaction(){
return $this->dbh->beginTransaction();
}



public function endTransaction(){
return $this->dbh->commit();
}



public function cancelTransaction(){
return $this->dbh->rollBack();
}


public function debugDumpParams(){
return $this->stmt->debugDumpParams();
}



///date copyright
public function copyright($year = 'auto'){
if(intval($year) == 'auto'){ $year = date('Y'); }
if(intval($year) == date('Y')){ echo intval($year); }
if(intval($year) < date('Y')){ echo intval($year) . ' - ' . date('Y'); }
if(intval($year) > date('Y')){ echo date('Y'); }
}


//get ip
public function getip()
{
if (!empty($_SERVER['HTTP_CLIENT_IP']))
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}

//filter
public function cleanInput($input) {
$search = array(
'@<script[^>]*?>.*?</script>@si', // Strip out javascript
'@<[/!]*?[^<>]*?>@si', // Strip out HTML tags
'@<style[^>]*?>.*?</style>@siU', // Strip style tags properly
'@<![sS]*?--[ tnr]*>@' // Strip multi-line comments
);
$output = preg_replace($search, '', $input);
return $output;
}



public function generateHash($plainText, $salt = null)
{
if ($salt === null)
{
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
}
else
{
$salt = substr($salt, 0, SALT_LENGTH);
}

return $salt . sha1($salt . $plainText);
}


}
?>

2undercover
چهارشنبه 06 آذر 1392, 20:10 عصر
پس همونطور که گفتم از این روش برای مقدار دهی پارامتر های عددی استفاده کنید:


$class->bind(1, !is_null($title) ? $title : '');

soroush.r70
چهارشنبه 06 آذر 1392, 20:27 عصر
ای بابا داستان داریم بازم خطا می ده حتما باید تمام فیلد ها پر باشه شاید من 5 تا فیلد داشته باشم شاید یه بار 4 تا شو پر کنم شاید یه 2 تا شو پر کنم چرا ثبت نمی شه وقتی فیلدی خالیه خطا می ده به صورت زیر عمل کردم بازم خطا می ده


$class->query("INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL,?,?)");
$class->bind(1, !is_null($ip) ? $ip : '');
$class->bind(1, !is_null($active) ? $active : '');
$class->execute();

الان تو کد بالا 2 تا فیلد دارم میام بعضی وقتا یکیشو پر می کنم خطا می ده و ثبت نمی شه دو تاشو پر می کنم ثبت می کنم چرا اینطوری می شه کلاس من مشکل داره نحوه ی ثبت مشکل داره چیه...؟

2undercover
پنج شنبه 07 آذر 1392, 07:26 صبح
ای بابا داستان داریم بازم خطا می ده حتما باید تمام فیلد ها پر باشه شاید من 5 تا فیلد داشته باشم شاید یه بار 4 تا شو پر کنم شاید یه 2 تا شو پر کنم چرا ثبت نمی شه وقتی فیلدی خالیه خطا می ده به صورت زیر عمل کردم بازم خطا می ده


$class->query("INSERT INTO `tbl_ip` (`id`,`ip`,`active`) VALUES (NULL,?,?)");
$class->bind(1, !is_null($ip) ? $ip : '');
$class->bind(1, !is_null($active) ? $active : '');
$class->execute();

الان تو کد بالا 2 تا فیلد دارم میام بعضی وقتا یکیشو پر می کنم خطا می ده و ثبت نمی شه دو تاشو پر می کنم ثبت می کنم چرا اینطوری می شه کلاس من مشکل داره نحوه ی ثبت مشکل داره چیه...؟

خوب اون آرگومان اول متد bind رو من به عنوان مثال 1 نوشته بودم و شما باید خودتون بر اساس کوئری اون عدد رو تغییر بدید. مثلا برای قسمت active شما باید عدد 2 رو به متد ارسال بکنید!

Mohammad.barati
چهارشنبه 20 آذر 1392, 16:05 عصر
با سلام
دانلود رایگان فیلم آموزشی کار با پایگاه داده در زبان php به روش pdo به زبان فارسی در آدرس زیر وجود دارد:
http://www.softcode.ir/%D9%81%DB%8C%D9%84%D9%85-%D9%87%D8%A7%DB%8C-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%DA%A9%D8%A7%D8%B1-%D8%A8%D8%A7-%D9%BE%D8%A7%DB%8C%DA%AF%D8%A7%D9%87-%D8%AF%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7/