🎉 سال نو، مهارت نو، مشاوره رایگان نقشه راه برنامه نویسی (آفر ویژه ثبت نام قبل از افزایش قیمت 🔥)
۰ ثانیه
۰ دقیقه
۰ ساعت
۴ امیر صالحی
خطا در کوئری زدن به دیتابیس
محسن موحد حل شده توسط محسن موحد

سلام و احترام

من در حال توسعه پروژه‌ای هستم که برای تمرین خودم تعریف کردم. الان رسیدم به بخش مدل (Model) که تو این قسمت منو اسیر کرده!

مشکل اینکه، همه چی درسته ولی داده توی دیتابیس نمیشینه، کوئری و .. همه چیو بررسی کردم ولی باز کار نمیکنه. اگه امکانش هست کدهای پایینو بررسی کنید و ببینید مشکل چیه؟

<?php
namespace Bootstrap;
use PDO as PDOAlias;
abstract class Model
{
    protected $dbh;
    protected $stmt;
    protected $table;
    protected $pk = 'id';
    protected $order_by = false;
    public function __construct()
    {
        $this->dbh = new PDOAlias("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . "", DB_USER, DB_PASS);
    }
    public function create($data)
    {
        $result = $this->getKeysAndValues($data, 'create');
        $stmt = $this->dbh->prepare($result['sql']);
        $stmt->execute($result['execute']);
        return $this->dbh->lastInsertId();
    }
    protected function getKeysAndValues($arr, $type = null)
    {
        $result = [];
        $execute = [];
        $sql = '';
        $sets = '';
        $keys = '';
        $i = 0;
        // extraction Keys
        foreach ($arr as $k => $v) {
            $execute += ["$k" => $v];
            if (count($arr) - 1 == $i) {
                $keys .= ":$k";
                $sets .= "$k";
                break;
            }
            $keys .= ":$k, ";
            $sets .= "$k, ";
            $i++;
        }
        $result += ["execute" => $execute];
        if ($type == 'create') {
            $sql = "INSERT INTO {$this->table} ({$sets}) VALUES ($keys)";
            $result += ["sql" => $sql];
            return $result;
        }
    }
}

متد create در اصل کار insert به دیتابیس رو انجام میده 

 

 

این خط کدت رو به این شکل بنویس : 

به جای PDO نوشتین PDOAlias

        $this->dbh = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . "", DB_USER, DB_PASS);

 

میثم ۲۸ خرداد ۱۳۹۹، ۱۳:۲۳

سلام. یادت رفته یه : داخل ایندکس‌های execute بذاری:

$execute += [":$k" => $v];

به جای += به این شکل هم میتونی بنویسی:

$execute[':' . $k] = $v;

 

محسن موحد ۲۸ خرداد ۱۳۹۹، ۱۴:۳۲

کلاستون بجز همون موردی که گفتم تست گرفتم، مشکلی نداره.

شاید توو ورودیها مشکل دارید و یا ... trace کنید و print_r بگیرید ببینید خروجی هر قطعه چی هست!

متد شمارو با استفاده از توابع خود PHP بازنویسی کردم:

protected function getKeysAndValues($arr, $type = null)
{
    if ($type == 'create') {
        $sql = "INSERT INTO {$this->table} (". implode(',', array_keys($arr)) .") VALUES (". implode(',', array_map(function($key) { return ':' . $key; }, array_keys($arr))) .")";
        $result = [
        	'execute' => array_combine(array_map(function($key) { return ':' . $key; }, array_keys($arr)), array_values($arr)),
        	'sql' => $sql
        ];
        echo '<pre>' . print_r($result, true) . '</pre>';
        return $result;
    }
}

 

برای تست کلاسو از حالت abstract در بیارید و خود کلاس Model رو از روش آبجکت بسازید و create رو صدا بزنید.

با توجه به الگوریتم شما، داده ی نمونه:

$obj = new Model;
$obj->create(['firstname' => 'mohsen', 'lastname' => 'movahed', 'email' => 'test@yahoo.com', 'reg_date' => 123]);

 

خروجی متغیر result در این مثال:

Array
(
    [execute] => Array
        (
            [:firstname] => mohsen
            [:lastname] => movahed
            [:email] => test@yahoo.com
            [:reg_date] => 123
        )
    [sql] => INSERT INTO myguests (firstname,lastname,email,reg_date) VALUES (:firstname,:lastname,:email,:reg_date)
)

 

بهترین پاسخ
محسن موحد ۲۸ خرداد ۱۳۹۹، ۱۵:۲۵

سلام مجدد.

این خطو بعد از ایجاد کانکشن PDO بذارید تا exception ای اگر اتفاق بیفته بره توو بلاک catch و خطارو نمایش بده:

$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

شما  در فرم اشتباهاً publish data نوشتید که در جدول وجود ندارد و در جدول فیلد publish date وجود دارد. مشکل برنامه همین فیلد هست که باید تصحیح کنید.

محسن موحد ۲۹ خرداد ۱۳۹۹، ۱۶:۲۵