کلاس نوشته شده در چه سطحی است ؟؟
خوب
33.33%
1
متوسط
66.67%
2
ضعیف
0%
0
3 رای
* چنانچه به گزینه‌ای رای داده اید، با علامت ستاره مشخص گردیده است. [نمایش نتایج]

  • 1 رای - 4 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
شروع oop با نوشتن کلاس دیتابیس و pdo
#1
با سلام

من قبلا از کدنویسی توی صفحات استفاده میکردم
اما واسه یه پروژه متوسط خیلی کدها تکراری میشه

الان میخوام برم به سمت oop

الان یه کلاس دیتابیس نوشتم میخوام بدونم مشکلاتش چیه ؟؟؟

البته اینم بگم خیلی از توابع هنوز نوشته نشده
اگر هم تمایل دارید میتونید توابعی که خودتون میدونید رو پست کنید

کد پی‌اچ‌پی:
<?php


class db{


    private 
$pdo;
        
    private 
$host='localhost';
    private 
$user='root';
    private 
$password='';
    private 
$database='tttt';
    
    public 
$stmt;
    private 
$err_msg;
    
    
    public function 
__construct()
    {
        
$this->open_connection();
    }
    
    
    public function 
open_connection()
    {    
        try
        {
            
$this->pdo=@new PDO("mysql:host=$this->host;dbname=$this->database;charset=utf8",$this->user,$this->password);            
                
            return 
true;                
            
        }
    
        catch(
PDOException $e)
        {    
            
$this->err_msg="Error : "$e->getMessage();
            return 
false;
        }
            
    }
    
    
    
    
    public function 
__destruct()
    {
        
$this->close_connection();
    }
    
    
    public function 
close_connection()
    {    
        if (isset(
$this->pdo))
        {
            
$this->pdo=null;
            unset(
$this->pdo);            
        }
        
    }
    
    
    
    public function 
query($sql)
    {
        try{
                
$result$this->pdo->query($sql);
                
                
$this->stmt=$result;            
           }
           
           catch(
PDOException $e)
           {  
                
$this->err_msg="Error : ".$e->getMessage();                   
           }        
    }
    
    
    public function 
prepare($sql,$param)
    {        
        try
        {
            
$stmt=$this->pdo->prepare($sql);
                                        
            if(
$stmt->execute($param))
            {            
                
$this->stmt=$stmt;            
                return 
true;                
            }
            
            return 
false;
        }
        catch(
PDOException $e)
        {        
            
$this->err_msg="Error : "$e->getMessage();            
            return 
false;
        }        
    }
    
    
    public function 
affectRow()
    {    
        return 
$this->stmt->rowCount();        
    }
    
    
    public function 
fetch_all()
    {
        return 
$this->stmt->fetchAll();    
    }
    
    
    public function 
fetch()
    {
        return 
$this->stmt->fetch();        
    }
    
    
    public function 
insert($table$data)
    {
        try
        {            
            
$fields="`".implode("`, `",array_keys($data))."`";    


            
$fieldsCountcount(array_values($data));
        
            
$placeholders='';
    
                for (
$i=0;$i<$fieldsCount;$i++)
                {    
                    
$placeholders.=" ? , ";
                }


            
$placeholders=rtrim($placeholders," ,");


            
$sql "INSERT INTO `{$table}` ({$fields}) VALUES ({$placeholders})";
    
             return (
$this->prepare($sql,array_values($data)))?true:false;


        }        
        catch(
PDOException $e)
        {        
            
$this->err_msg="Error : "$e->getMessage();
            return 
false;
        }    
    }




    public function 
last_insert_id()
    {       
        return 
$this->pdo->lastInsertId();
    }
    
    
    public function 
getError()
    {
        return 
trim($this->err_msg)!="" $this->err_msg "";
    }







ساخت نمونه از کلاس و تست اون

کد پی‌اچ‌پی:
$db=new db();


$bb=$db->prepare("select * from  MENU where id>=?",array(9));




echo (
$bb?"true":"false")."<br>";




echo 
$db->affectRow()."<br>";


$r=$db->fetch_all();


foreach (
$r as $k=>$v)
{    
    echo 
$v['label']."-".$v['link']."<br>";
}




$db->query("UPDATE MENU set label='test',link='linetest',sort='4' where id>10");


echo 
$db->affectRow()."<br>";




$tt=$db->insert('menu',array("label"=>"test1","link"=>"#link1","parent"=>"0","sort"=>""));




echo 
$db->affectRow()."<br>";


echo 
$db->last_insert_id()."<br>";




?>
  پاسخ
تشکر شده توسط :
#2
اگر قصد دارید که این کلاس را حرفه توسعه و مورد استفاده قرار دهید، پیشنهاد می کنم که حتما آن را روی github قرار داده و از نسخه گزاری برای آن فراموش نشود.
این کار به شما این امکان توسعه برنامه، رفع مشکلات و خطاها و افزودن قابلیت های بیشتر را در یک وسعت زیادی از توسعه دهندگان قرار می دهد.
سالهــــا مـــــى گــــــذرد، حادثه ها مى آید
انتظـــــار فـــــــرج از نیمـــــه خــــــرداد کشم

[عکس: ShowPicture.aspx?ID=52750d12-5d92-4286-9...height=100]
  پاسخ
تشکر شده توسط : Y.P.Y ImanAzadi
#3
برای شروع کار با OOP خوب نوشتیش... تقریباً بی نقصه

ولی چند پیشنهاد:
این دستور رو بد نیست داخل همین فایل در بالای کلاست قرار بدی:
کد پی‌اچ‌پی:
if(!ini_get('safe_mode')) set_time_limit(0); 

همچنین شاید بد نباشه برای دسته بندی بهتر کدها و متدها، open_connection رو داخل construct__ قرار ندی و جداگانه صداش بزنی. و construct رو هم اینطوری بنویسی:
کد پی‌اچ‌پی:
public function __construct($Host '127.0.0.1'$Username 'root'$Password NULL$Database 'Database')
{
    
$this->host $Host;
    
$this->user $Username;
    
$this->password $Password;
    
$this->database $Database;
    
$this->stmt NULL;
    
$this->err_msg NULL;
    return;


همچنین نظرت چیه کمی universal تر کنیش و آدرس port و Persistency بودن/نبودن اتصال رو هم به کلاست اضافه کنی؟

بعلاوه اگر یک متد برای ایمن سازی کوئری بهش اضافه کنی کاملتر هم میشه...
مثلا همچین چیزی:
کد پی‌اچ‌پی:
public function safeQuery($Query)
{
    if (
function_exists('mysqli_real_escape_string') && $this->$pdo) return mysqli_real_escape_string($Query$this->$pdo);

    return 
addslashes($Query);


در آخر، یک متد هم برای دریافت version دیتابیس بزاری بد نیست. واسه setup/config کردن لازمت میشه...
کد:
توسط
SELECT VERSION()
یا
$pdo->getAttribute(PDO::ATTR_SERVER_VERSION)


در مورد شیوه کدنویسیت، برای خوانایی بهتر، بین هر متد/تابع یک خط فاصله بزار نه دوتا. بعلاوه اطراف اپراتور ها (مثل = - + * &) یک فاصله بزار و نچسبون به هم.
همچنین یه بین ' و " کمی تفاوت پرفورمنس هست و بهتره که هرکدوم در جای خودش استفاده بشه.
' برای Simple string هاست و سرعتش بیشتره.
" برای Variable/Dynamic string هاست و سرعتش کمتره.
وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط : sara147 ImanAzadi ضحاک
#4
میتونید خود کلاس pdo رو extend کنید.
به یـزدان که گر ما خرد داشتیم
کجـا این سر انجـام بد داشتیم؟
  پاسخ
تشکر شده توسط : ImanAzadi
#5
با تشکر از نظرات شما دوستان عزیز

نقل قول:همچنین شاید بد نباشه برای دسته بندی بهتر کدها و متدها، open_connection رو داخل construct__ قرار ندی و جداگانه صداش بزنی. و construct رو هم اینطوری بنویسی:

منظورتون اینه که واسه هر دستور کانکشن رو open کنیم (مثلا در دستور insert , یا query ) ???

نقل قول:بعلاوه اگر یک متد برای ایمن سازی کوئری بهش اضافه کنی کاملتر هم میشه...

مگر دستور prepare خودش ایمن سازی رو انجام نمیده ؟؟؟؟؟

نقل قول:در آخر، یک متد هم برای دریافت version دیتابیس بزاری بد نیست. واسه setup/config کردن لازمت میشه...

کد پی‌اچ‌پی:
توسط
SELECT VERSION
()
یا 
$pdo
->getAttribute(PDO::ATTR_SERVER_VERSION


این متد کجا به کار میاد و چه استفاده ای داره ؟؟؟

با تشکر
  پاسخ
تشکر شده توسط :
#6
نقل قول: همچنین شاید بد نباشه برای دسته بندی بهتر کدها و متدها، open_connection رو داخل construct__ قرار ندی و جداگانه صداش بزنی. و construct رو هم اینطوری بنویسی:
نقل قول:منظورتون اینه که واسه هر دستور کانکشن رو open کنیم (مثلا در دستور insert , یا query ) ???
نه. یعنی مقادیرت رو در متد construct تنظیم کن. و کانکشن رو در open_connection باز کن.
ولی کاری که شما کردی open_connection رو در construct قرار دادی و مقادیر رو در بالای کلاس تنظیم کردی.


نقل قول: بعلاوه اگر یک متد برای ایمن سازی کوئری بهش اضافه کنی کاملتر هم میشه...
نقل قول:مگر دستور prepare خودش ایمن سازی رو انجام نمیده ؟؟؟؟؟
فقط برای حملات ابتدایی/آماتوری، آره. ولی:
حملات SQL Injection در دو مرحله انجان میشه. و از اونجایی که دستور Prepare با دستور mysql_real_escape_string ترکیب شده که از API خود MySQL هم استفاده کرده(در مثال شما)، پس فقط مرحله اول/قسمت اول رو تضمین میکنه.
درواقع توابع/API این PDO از لایه ها میاد: PDO MySQL lib -> MySQLi lib -> PHP lib

درضمن فکر نمی کنم mysql_real_escape_string بتونه از این نوع حملات جلوگیری کنه:
کد پی‌اچ‌پی:
$_GET['id'] = '1 OR 1=1';
$id mysql_real_escape_string($_GET['id']);
$sql "SELECT * FROM mytable WHERE myid = {$id}"
یا
کد پی‌اچ‌پی:
$pdo->query('SET NAMES gbk');
$stmt $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("\xbf\x27 OR 1=1 /*")); 


نقل قول:در آخر، یک متد هم برای دریافت version دیتابیس بزاری بد نیست. واسه setup/config کردن لازمت میشه...
نقل قول:این متد کجا به کار میاد و چه استفاده ای داره ؟؟؟
گفتم دیگه... برای وقتی که میخوای یه Installer واسه پروژت بنویسی. یا مثلاً از پنل admin کانفیگش کنی، یا داده هات رو تبدیل کنی(user friendly تر) بشه، یا نوع دیتابیس رو تغییرش بدی و...
وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط : ImanAzadi


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان