Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Vingrad CMS > Класс для работы с базой


Автор: Wowa 17.6.2005, 14:35
В принципе, можно написать свой класс, но есть уже готовый и довольно хороший. А писать самому - будет примерно тоже самое. Давайте этот класс возьмем за основку для работы с базой.
Код

<?php
//****************************************************************************
// phpDatabase 2.1
//****************************************************************************
//      Author: Maxim Poltarak  <maxx at e dash taller dot net>
//    Category: Databases
//****************************************************************************
// The lib is FREEWARE. This means you may use it anywhere you want, you may 
// do anything with it. The Author mentioned above is NOT responsible for any 
// consequences of using this library. 
// If you don't agree with this, you MAY NOT use the lib!
//****************************************************************************
// All improvings, feature requests, bug reports, etc. are gladly accepted.
//****************************************************************************
// Note: For best viewing of the code Tab size 4 is recommended
//****************************************************************************
class CDatabase {
    var $link;
    var $db;
    var $host, $user, $pass;

    function CDatabase($db, $host="localhost", $user="", $pass="") {
        $this->db = $db; $this->host = $host; $this->user = $user; $this->pass = $pass;
        if($this->link = mysql_connect($host,$user,$pass))
            return mysql_select_db($db, $this->link);
            else return 0;
    }

    function query($sql) {    
        if(!$this->link) return 0;
        return mysql_query($sql, $this->link);
    }

    function affected_rows() {
        return mysql_affected_rows($this->link);
    }

    function num_rows($q) {
        return mysql_num_rows($q);
    }

    function fetch_array($q, $result_type=MYSQL_ASSOC) {
        return mysql_fetch_array($q, $result_type);
    }

    function fetch_object($q) {
        return mysql_fetch_object($q);
    }

    function data_seek($q, $n) {
        return mysql_data_seek($q, $n);
    }

    function free_result($q) {
        return mysql_free_result($q);
    }

    function insert_id() {
        return mysql_insert_id($this->link);
    }

    function error() {
        return mysql_error($this->link);
    }

    function error_die($msg='') {
        die(((empty($msg))?'':$msg.': ').$this->error());
    }

    function sql2var($sql) {
        if((empty($sql)) || (!($query = $this->query($sql)))) return false;
        if($this->num_rows($query) < 1) return false;
        return $this->result2var($query);
    }

    function result2var($q) {
        if(!($Data = $this->fetch_array($q))) return false;
        $this->free_result($q);
        foreach($Data as $k=>$v) $GLOBALS[$k] = $v;
        return true;
    }

    function sql2array($sql, $keyField='') {
        if((empty($sql)) || (!($query = $this->query($sql)))) return false;
        if($this->num_rows($query) < 1) return false;
        return $this->result2array($query, $keyField);
    }

    function result2array($q, $keyField='') {
        $Result = array();
        while($Data = $this->fetch_array($q))
            if(empty($keyField)) $Result[] = $Data;
            else $Result[$Data[$keyField]] = $Data;
        $this->free_result($q);
        return $Result;
    }

    function list_tables() {
        return mysql_list_tables($this->db, $this->link);
    }

    function list_fields($table_name) {
        return mysql_list_fields($this->db, $table_name, $this->link);
    }
    function db_row($query) {
      $r=mysql_query($query);
        //  if (!$r) die(mysql_error());
       if (!$r) die("MySQL error ".mysql_errno().": ".mysql_error()."\n<br>When executing:<br>\n$query\n<br>");
       if (!mysql_num_rows($r)) return array();
        //  if (!mysql_num_rows($r)) return 0;
       return mysql_fetch_array($r);
    }
};

?>


Или будут еще какие-либо предложения у кого-то?

Автор: Mal Hack 17.6.2005, 17:49
Код
<?php

 if( ! defined( "KERNEL" ) )
  {  exit( "System error." );  }

 class SQL_Driver extends SQL_Global
  {
   var $Connected              = TRUE;
   var $Handle                 = NULL;
   var $Result                 = NULL;
   var $Query_Count            = 0;
   var $Query                  = array();
   var $Query_Error_Text       = array();
   var $Query_Error_Number     = 0;
   var $Count_Rows             = array();
   var $Count_Cols             = array();
   var $DataObj                = array( array() );
   var $Fields                 = array( array() );
   var $Query_Insert_Id        = array();

   function SQL_Driver( $h , $p , $u , $ps , $b )
    {
     $h              = ( ! empty( $p ) ) ? $h . ":" . $p : $h ;
     $this -> Handle = @ mysql_connect( $h , $u , $ps );

     if( $this -> Handle )
      {  $this -> Connected = TRUE ;  }

     if( @ mysql_select_db( $b , $this -> Handle ) == TRUE )
      {  $this -> Connected = TRUE ;  }
    }

   function __destruct()
    {  @ mysql_close( $this -> Handle );  }

   function SQl_Query( $query )
    {
     $this -> Query_Count++;

   #  print
     $this -> Query[ $this -> Query_Count ] = $query;
   #  print "<br>";
     $this -> Result = @ mysql_query( $this -> Query[ $this -> Query_Count ] , $this -> Handle );

     preg_match( "/^\s*((create\s*[^\s]+)|(show\s*[^\s]+)|([^\s]+))/i" , $this -> Query[ $this -> Query_Count ] ,  $matches );
     $this -> Query_Type[ $this -> Query_Count ] = strtoupper( $matches[1] );

     print $this -> Query_Error_Text[ $this -> Query_Count ] = mysql_error( $this -> Handle );
     $this -> Query_Error_Number = mysql_errno( $this -> Handle );

     if( $this -> Query_Error_Number != 0 )
      {  return FALSE;  }

     switch( $this -> Query_Type[ $this -> Query_Count ] )
      {
       case "SELECT":           $ret = $this -> SQl_Get_DataObj();
                                mysql_free_result( $this -> Result );
            break;
       case "INSERT":           $this -> Query_Insert_Id[ $this -> Query_Count ] = @ mysql_insert_id( $this -> Result );
                                $ret = TRUE;
            break;
       default:                 $ret = TRUE;
            break;
      }

     return $ret;
    }

   function SQl_Get_DataObj()
    {
     $this -> Count_Rows[ $this -> Query_Count ] = mysql_num_rows( $this -> Result );
     $this -> Count_Cols[ $this -> Query_Count ] = mysql_num_fields( $this -> Result );
     $this -> SQL_Get_fields_name();

     if ( $this -> Count_Rows[ $this -> Query_Count ] <= 0 )
      {  return FALSE;  }

     $i = 0;
     while( $this -> DataObj[ $this -> Query_Count ][$i] = mysql_fetch_object( $this -> Result ) )
      {  $i++;  }

     return TRUE;
    }

   function SQL_Get_fields_name()
    {
     for( $i = 0 ; $i < $this -> Count_Cols[ $this -> Query_Count ] ; $i++ )
      {  $this -> Fields[ $this -> Query_Count ][$i] = mysql_field_name( $this -> Result , $i );  }
    }
  }

?>

Автор: Irokez 17.6.2005, 19:24
для работы с базой:
Код

<?php
/*
    db.class.php - contains ICM_DBase class description
*/

$GLOBALS['DB']=xparse_ini_file("{$GLOBALS['PTH']['conf']}dbase.conf", false);   //database configs

/*
    class ICM_DB - class to work with database
    implements work with mysql database
*/
class ICM_DB
{
    var $_link;     //link to mysql database
    var $_host;     //database host
    var $_login;    //database login
    var $_pass;     //database password
    var $_name;     //database name
    /* methods:
    bool ICM_DB()
    mixed exeQuery(string query)
    mixed getResult(string query)
    array getTables()
    array getFields(string table_name)
    int lastID()
    */

/*
    constructor, connects to database
    receives database attributes
    returnes true if connected
*/
    function ICM_DB()
    {
        $this->_host=$GLOBALS['DB']['host'];
        $this->_login=$GLOBALS['DB']['login'];
        $this->_pass=$GLOBALS['DB']['pass'];
        $this->_name=$GLOBALS['DB']['name'];
        $this->_link=mysql_connect($this->_host,$this->_login,$this->_pass);
        return mysql_select_db($this->_name,$this->_link);
    }

/*
    executes mysql query
    receives given query
    returnes mysql result
*/
    function exeQuery($query)
    {
        if($GLOBALS['DB']['show_error'])
            $result=mysql_unbuffered_query($query,$this->_link)
                or die("Error ".mysql_errno().': '.mysql_error()."<br>Query: ".nl2br($query));
        else
            $result=mysql_query($query,$this->_link);
        return $result;
    }

/*
    executes mysql query and returnes result
    receives string
    returnes result
*/
    function getResult($query)
    {
        $result=$this->exeQuery($query);
        $data=mysql_fetch_array($result);
        return $data[0];
    }

/*
    gets list of tables in current database
    receives nothing
    returnes names of tables
*/
    function getTables()
    {
        $tables_names=array();
        $tables=mysql_list_tables($this->_name, $this->_link);
        $property_name='Tables_in_'.$this->_name;
        while($table=mysql_fetch_object($tables))
            array_push($tables_names, $table->$property_name);
        return $tables_names;
    }

/*
    gets fields' names of a given table
    receives table name
    returnes fields names
*/
    function getFields($table)
    {
        $fields=mysql_list_fields($this->_name, $table, $this->_link);
        $fields_num=mysql_num_fields($fields);
        for($i=0; $i<$fields_num; $i++)
            $fields_names[$i+1]=mysql_field_name($fields, $i);
        return $fields_names;
    }

/*
    gets id of last inserted row
    receives nothing
    return ID
*/
    function lastID()
    {
        return mysql_insert_id($this->_link);
    }
}
?>


для работы с таблицей:
Код

<?php
/*
    table.class.php - contains ICM_Table class description
*/

$GLOBALS['TBL']=xparse_ini_file("{$GLOBALS['PTH']['conf']}tables.conf", true);  //tables' configs
require_once "db.class.php";    //ICM_DB description

/*
    class ICM_Table - class to work with database tables
*/
class ICM_Table
{
    var $db;       //database object
    var $_name;    //table name
    var $_trans;   //postfix for tables with translatable data
    var $_item;    //key-item field name
    var $_lang;    //language field name
    /* methods:
    bool ICM_Table(array table_attrib)
    int insert(array data)
    bool update(int id, array data)
    bool delete(int id)
    array select(int id)
    array all([...])
    array selectAll([...])
    mixed getValue(int id, string field);
    mixed getTValue(int id, int lang, string field);
    */

/*
    constructor
    receives table attributes
    returnes true
*/
    function ICM_Table($table_name, $trans_postfix, $keyitem, $langfield)
    {
        $this->db=new ICM_DB;
        $this->_name=$table_name;
        $this->_trans=$trans_postfix;
        $this->_item=$keyitem;
        $this->_lang=$langfield;
        return true;
    }

/*
    inserts data in table
    receives data to insert
    returnes inserted ID
*/
    function insert($data)
    {

        /*
            first parse data, get fields and values
            if $data[$field] is an array it means that it's translatable data
            where $data[$field][$lang] - is it's value and $lang - language ID
        */
        foreach($data as $field => $value)
            if(!is_array($value))
            {
                if(isset($fields)) $fields.=", `$field`";
                else $fields="`$field`";
                if(isset($values)) $values.=" ,'$value'";
                else $values="'$value'";
            }
            else
                foreach($value as $lang => $value_trans)
                {
                    if(isset($fields_trans[$lang])) $fields_trans[$lang].=", `$field`";
                    else $fields_trans[$lang]="`$field`";
                    if(isset($values_trans[$lang])) $values_trans[$lang].=", '$value_trans'";
                    else $values_trans[$lang]="'$value_trans'";
                }

        /*
            insert data
        */
        $query="insert into `{$this->_name}` ($fields) values ($values)";
        $result=$this->db->exeQuery($query);
        $last_id=$this->db->lastID();

        /*
            if there is translatable data then insert it
        */
        if(isset($fields_trans))
            foreach($fields_trans as $lang => $fields)
            {
                $values=$values_trans[$lang];
                $query="insert into `{$this->_name}{$this->_trans}` (`{$this->_item}`, `{$this->_lang}` ,$fields)
                        values ('$last_id', '$lang', $values)";
                $result=$this->db->exeQuery($query);
            }

        return $last_id;
    }

/*
    updates data in table
    receives ID of a row, data to update
    returnes true if succeed
*/
    function update($id, $data)
    {

        /*
            first check if there is row with such ID
            if not we insert data instead of updating it
        */
        $query="select count(*) from `{$this->_name}` where `id`='$id'";
        $num=$this->db->getResult($query);
        if($num)
        {
            /*
                like in insert(), we parse data first
            */
            foreach($data as $field => $value)
                if(!is_array($value))
                    if(isset($sets)) $sets.=", `$field`='$value'";
                    else $sets="`$field`='$value'";
                else
                    foreach($value as $lang => $value_trans)
                    {
                        $query="select count(*) from `{$this->_name}{$this->_trans}`
                                where `{$this->_item}`='$id' and `{$this->_lang}`='$lang'";
                        $num=$this->db->getResult($query);
                        if($num)
                            if(isset($sets_trans[$lang])) $sets_trans[$lang].=", `$field`='$value_trans'";
                            else $sets_trans[$lang]="`$field`='$value_trans'";
                        else
                            $query="insert into `{$this->_name}{$this->_trans}`
                                    (`{$this->_item}`, `{$this->_lang}`, $field)
                                    values ('$id', '$lang', '$value_trans')";
                            $this->db->exeQuery($query);
                    }

            /*
                update data
            */
            $query="update `{$this->_name}` set $sets where `id`='$id'";
            $result=$this->db->exeQuery($query);

            /*
                update translatable data
            */
            if(isset($sets_trans))
                foreach($sets_trans as $lang => $set)
                {
                    $query="update `{$this->_name}{$this->_trans}`
                            set $set
                            where `{$this->_item}`='$id' and `{$this->_lang}`='$lang'";
                    $result=$this->db->exeQuery($query);
                }
        }
        else
        {
            $data['id']=$id;
            $result=$this->insert($data);
        }
        return (bool)$result;
    }

/*
    deletes data from table
    receives ID of a row to delete
    returnes true if succeed
*/
    function delete($id)
    {

        /*
            delete data
        */
        $query="delete from `{$this->_name}` where `id`='$id'";
        $result=$this->db->exeQuery($query);

        /*
            delete translatable data if exists
        */
        if(in_array($this->_name.$this->_trans, $this->db->getTables()))
        {
            $query="delete from `{$this->_name}{$this->_trans}` where `{$this->_item}`='$id'";
            $result=$this->db->exeQuery($query);
        }

        return (bool)$result;
    }

/*
    gets row with given ID
    receives row ID
    returnes associative array of data or empty array if row does not exists
*/
    function select($id)
    {
        $data=array();

        /*
            check whether row with given ID exists
        */
        $query="select count(*) from `{$this->_name}` where `id`='$id'";
        $num=$this->db->getResult($query);
        if($num)
        {
            /*
                get data
            */
            $query="select * from `{$this->_name}` where `id`='$id'";
            $result=$this->db->exeQuery($query);
            $data=mysql_fetch_assoc($result);
            mysql_free_result($result);

            /*
                get translatable data if exists
            */
            if(in_array($this->_name.$this->_trans, $this->db->getTables()))
            {
                /*
                    list of system fields
                    we do not need to select from table with translatable data
                */
                $sys_fields=array('id', $this->_item, $this->_lang);

                $query="select * from `{$this->_name}{$this->_trans}` where `{$this->_item}`='$id'";
                $result=$this->db->exeQuery($query);
                while($tdata=mysql_fetch_assoc($result))
                    foreach($tdata as $field => $value)
                        if(!in_array($field, $sys_fields))
                            $data[$field][$tdata[$this->_lang]]=$value;
            }
        }

        return $data;
    }

/*
    gets all data from table
    receives:
        nothing
        or: where
        or: start, limit
        or: order, [dir]
        or: start, limit, order, [dir], [where]
    returnes array of IDs
*/
    function all()
    {

        /*
            get arguments and parse them
        */
        $args=func_get_args();
        $args_num=count($args);

        if($args_num==1)
        {
            if(is_string($args[0])) $where=$args[0];
            elseif(is_numeric($args[0])) $limit=$args[0];
        }
        elseif($args_num==2)
        {
            if(is_numeric($args[0]) && is_numeric($args[1]))
            {
                $start=$args[0];
                $limit=$args[1];
            }
            elseif(is_string($args[0]) && is_string($args[1]))
            {
                $order=$args[0];
                $dir=$args[1];
            }
        }
        elseif($args_num>=3)
        {
            if(is_numeric($args[0])) $start=$args[0];
            if(is_numeric($args[1])) $limit=$args[1];
            if(is_string($args[2])) $order=$args[2];
            if(isset($args[3])) if(is_string($args[3])) $dir=$args[3];
            if(isset($args[4])) if(is_string($args[4])) $where=$args[4];
        }

        $row=array();
        $order4query='';
        $limit4query='';
        $where4query='';

        if(isset($order))
        {
            if(in_array($this->_name.$this->_trans, $this->db->getTables()))
                $all_fields=array_merge($this->db->getFields($this->_name), $this->db->getFields($this->_name.$this->_trans));
            else
                $all_fields=$this->db->getFields($this->_name);
            if(in_array($order, $all_fields))
            {
                $order4query="order by `$order`";
                if(isset($dir))
                    if(in_array($dir, array('desc', 'asc'))) $order4query.=" $dir";
            }
        }
        if(isset($limit))
        {
            if(isset($start)) $limit4query="limit $start, $limit";
            else $limit4query="limit $limit";
        }
        if(isset($where)) $where4query=" $where";

        if(in_array($this->_name.$this->_trans, $this->db->getTables()))
            $query="select tbl.id from `{$this->_name}` as tbl, `{$this->_name}{$this->_trans}` as tbl_t
                    where tbl.id=tbl_t.{$this->_item} $where4query $order4query $limit4query";
        else
            $query="select id from `{$this->_name}`
                    where 1 $where4query $order4query $limit4query";

        $result=$this->db->exeQuery($query);
        while($data=mysql_fetch_assoc($result))
            if(!in_array($data['id'], $row)) array_push($row, $data['id']);

        return $row;
    }

/*
    selects all data from table
    gets all data from table
    receives:
        nothing
        or: where
        or: start, limit
        or: order, [dir]
        or: start, limit, order, [dir], [where]
    returnes associative array of data
*/
    function selectAll()
    {
        $data=array();
        $args=func_get_args();
        $rows=call_user_func_array(array(&$this, 'all'), $args);
        foreach($rows as $id)
            array_push($data, $this->select($id));
        return $data;
    }

/*
    gets field value of row with given ID, if such exists
    receives row ID and field name
    returnes field value or false if row doesn't exists
*/
    function getValue($id, $field)
    {
        $value=false;

        /*
            check whether row with given ID exists
        */
        $query="select count(*) from `{$this->_name}` where id='$id'";
        $num=$this->db->getResult($query);
        if($num)
        {
            /*
                check whether given field exists
            */
            if(in_array($field, $this->db->getFields($this->_name)))
            {
                $query="select `$field` from `{$this->_name}` where `id`='$id'";
                $value=$this->db->getResult($query);
            }
        }

        return $value;
    }

/*
    gets value of translatable field
    receives row ID, language ID, field name
    returnes field value or false if does not exists
*/
    function getTValue($id, $lang, $field)
    {
        $value=false;

        /*
            check whether row with given ID and language ID exists
        */
        $query="select count(*) from `{$this->_name}{$this->_trans}`
                where `{$this->_item}`='$id' and `{$this->_lang}`='$lang'";
        $num=$this->db->getResult($query);
        if($num)
        {
            /*
                check whether given field exists
            */
            if(in_array($field, $this->db->getFields($this->_name.$this->_trans)))
            {
                $query="select `$field` from `{$this->_name}{$this->_trans}`
                        where `{$this->_item}`='$id' and `{$this->_lang}`='$lang'";
                $value=$this->db->getResult($query);
            }
        }

        return $value;
    }

}
?>

Автор: Рыжий 17.6.2005, 20:49
хм, в книге ПРоффесиональное PHP программирование давалось class db - простой API для работы с базой данных, чем он плох?? smile

Автор: Irokez 17.6.2005, 20:53
Цитата(PHP @ 17.6.2005, 20:49)
чем он плох??

тем что мы его не видели smile

Автор: Рыжий 17.6.2005, 22:49
Я вообщето его с книги наьирал, поэтому могут быть синтаксические ошибки smile Но помоему сам скрипт можно скачать с wrox.com ну ладно вот код:

Код

<?php<?php
class db
{
        /* параметры соединения*/
        var $host = '';
        var $user = '';
        var $password = '';
        var $database = '';
        var $persistent=false;

        /*Дескриптор соединения с Базой Данных*/
        var $conn = NULL;

        /*Результат запроса */
        var $result=false;

            function db($host,$user,$password,$database,$persistent=false)
                 {
                  $this->host = $host;
                  $this->user = $user;
                  $this->password = $password;
                  $this->database = $database;
                  $this->persistent = $persistent;
                 }
            function open()
                 {
                  /*Выбрать соответствующую функцию соединения*/
                  if ($this->persistent){
                          $func = 'mysql_pconnect';
                          }
                          else
                          {
                           $func = 'mysql_connect';
                          }
                  /*соединиться с сервером MySQL*/
                  $this->conn = $func($this->host,$this->user,$this->password);
                  if(!$$this->conn)
                       {
                       return false;
                       }
                  /*Выбрать запрошенную базу данных*/
                  if (@!mysql_select_db($this->database,$this->conn))
                       {
                        return false;
                       }
                       return true;
                 }

             function close()
                  {
                   return(@mysql_close($this->conn));
                  }

             function error()
                  {
                   return (mysql_error());
                  }

             function query($sql)
                  {
                   $this->result = @mysql_query($sql,$this->conn);
                   return($this->result!=false);
                  }

             function affectedrows()
                  {
                   return(@mysql_affected_rows($this->conn));
                  }

             function numrows()
                  {
                   return (@mysql_num_rows($this->result));
                  }

             function fetchobject()
                  {
                   return (@mysql_fetch_object($this->result,MYSQL_ASSOC));
                  }

             function fetcharray()
                  {
                   return(@mysql_fetch_array($this->result,MYSQL_NUM));
                  }

             function fetchassoc()
                  {
                   return(@mysql_fetch_assoc($this->result));
                  }

             function freeresult()
                  {
                   return(@mysql_free_result($this->result));
                  }
}
?>[s]

Автор: Mal Hack 17.6.2005, 22:57
PHP-Script
Этот класс имхо не даст той универсальности.
ИМХО, слишком прост.

Автор: Рыжий 18.6.2005, 00:03
Mal Hack
Будь проще и к тебе потянутся smile
а почему ты считаешь что нужно извращаться?? (просто вопрос для себя...)

Автор: Gold Dragon 18.6.2005, 10:53
а правда, чем плох этот простой класс?
Mal Hack, твой вариант что-то слишком навороченный (но может он и лучше smile ). Пояни тогда

Автор: Wowa 18.6.2005, 11:37
Мне нравится мой вариант smile

Автор: Рыжий 18.6.2005, 12:04
Ну вот, начинается лебедь рак и щука - каждый в свою сторону... smile

Автор: Opik 18.6.2005, 14:12
Думаю класс не нужен, ибо будем ориентироваться на развитие PHP?
А в такой штуке как PHP 5.1 есть другая штука - PDO
http://ee.php.net/pdo

Автор: Wowa 18.6.2005, 14:27
Цитата(Opik @ 18.6.2005, 13:12)
Думаю класс не нужен, ибо будем ориентироваться на развитие PHP?
А в такой штуке как PHP 5.1 есть другая штука - PDO
http://ee.php.net/pdo

Очень хорошо, но пока это вещь сырая - думаю нужен собственный класс. Методы можно назвать также. Чтобы в будущем при необходимости подменить одно - другим не составило труда.

Автор: Opik 18.6.2005, 14:31
Wowa
Я думаю лучше сразу писать на эту вещь, хоть и сыроватую..А потом, если она сгинет (тьфу тьфу тьфу) то написать аналогичный класс.

Автор: Wowa 18.6.2005, 15:40
Цитата(Opik @ 18.6.2005, 13:31)
Я думаю лучше сразу писать на эту вещь, хоть и сыроватую..А потом, если она сгинет (тьфу тьфу тьфу) то написать аналогичный класс.

Для этого надо всем ставить новейшую версию ПХП. А если будут найдены баги, то снова ПХП обновлять. Обновление ПХП на веб-серверах - частенько не так легко и быстро, как кажется.

Автор: Opik 18.6.2005, 15:42
Wowa
к кому времени как мы закончим писать... будет намного стабильнее - я уверен.

Автор: Wowa 18.6.2005, 15:44
Цитата(Opik @ 18.6.2005, 14:42)
к кому времени как мы закончим писать... будет намного стабильнее - я уверен.

Но на данный момент - вещь сырая. И с ней имхо лучше не работать. Аргументируй плиз, свое желание работать с PDO. Что такое даст нам PDO, чего не даст нам свой класс?
Добавлено @ 15:47
Впрочем, я согласен, что PDO очень заманчиво выглядит.

Автор: Opik 18.6.2005, 15:52
Цитата
Аргументируй плиз, свое желание работать с PDO. Что такое даст нам PDO

1) Простота - не нужно писать свои драйвера - просто подключил и подредактировал конструктор
2) быстродейсвие
Да тут много интересного читайте сами: http://ee.php.net/pdo

Автор: Sardar 18.6.2005, 17:04
Согласен с Opik, ваши классы это просто перевызов функций MySQL, т.е. конкретная имплементация драйвера БД.

А те кро работал не только с MySQL знают что разработчики БД часто плевать хотели на стандарты и для каждой БД иногда требуеться чуть чуть подправить SQL запрос.

PDO уже имеет несколько драйверов, а не один под MySQL smile + патчер запросов. Короче большая работа уже сделана.

Автор: Рыжий 18.6.2005, 17:31
Если писать актуальную cms - могу согласиться с opik'ом - действительно нужно использовать САМЫЕ последние технологии, но все же не отрицаю что PDO - не на 100% рабочем уровне smile

Автор: Wowa 18.6.2005, 17:51
Цитата
Это расширение является ЭКСПЕРИМЕНТАЛЬНЫМ. Поведение этого расширения, включая имена его функций и относящуюся к нему документацию, может измениться в последующих версиях PHP без уведомления. Используйте это расширение на свой страх и риск.


Остается только надеятся, что очень много изменено не будет.
Добавлено @ 17:55
Получается, что нам надо будет ставить PHP 5.1.0 Beta 1 и с ним работать. Я не люблю работать с бета-версиями продуктов.

Автор: Рыжий 18.6.2005, 18:15
Цитата(Wowa @ 18.6.2005, 13:27)
Очень хорошо, но пока это вещь сырая - думаю нужен собственный класс. Методы можно назвать также.

Тогда в итоге у нас получится PDO smile

Автор: Medved 18.6.2005, 19:12
А мне кажется, что надо создать один абстрактный класс для работы с БД. Который и будет использоваться при написании всего приложения.
А методы для работы с каждой конкретной БД подлючать в виде "картриджей".

Проще говоря можно будет использользовать непосредственно несколько различных БД для хранения данных (MySQL, PostgreSQL, MSSQL, ORACLE (!) что очень важно для более менее-крупных заказчиков, и т.д.). При установке пользователь сам будет указывать какую БД использовать, и настраивать коннект.

Это будет "фишкой" этого продукты, и соответсвенно увеличивает его конкурентноспособность.

Затрат на это много не потребуется, просто необходимо грамотно продумать объектную модель приложения.

Тут конечно лучше всего было бы этот реализовать через интерфейсы, но в PHP они насколько я понимаю не поддерживаются. А жаль smile . Но можно обойтись и без интерфейсов.

Да и приложение будет проще сопровождать при таком подходе.


(вообще, проекты такого уровня, я рекомендовал бы писать на Java, вся мощь IT в твоих руках, PHP имхо слишком слаб для проектов такого уровня, и что самое главное - небезопасен)

Автор: Рыжий 18.6.2005, 19:21
Стоп а разве PDO не работает со всеми базами?? smile

Автор: Medved 18.6.2005, 19:27
Цитата(PHP @ 18.6.2005, 22:21)
Стоп а разве PDO не работает со всеми базами??

Я не рекомендовал бы использовать PDO.
Во первых - оно эксперементальное, а во вторых если в чем-нибудь будет затор, мы не сможем что-либо изменить, и в итоге будем стоять на одном месте. ИЛи придется все переписывать, или вести долгую переписку с авторами расширения.
Я уже сталкивался с такими случаями.

Автор: Opik 19.6.2005, 00:59
Цитата
Тут конечно лучше всего было бы этот реализовать через интерфейсы, но в PHP они насколько я понимаю не поддерживаются

кой какие интерфайсы есть в пятерке.

Автор: IZ@TOP 20.6.2005, 19:59
Я конечно понимаю на счет того почему стоит использовать PDO, но для начала стоит задуматься для кого и для чего мы пишем нашу CMS? Смогут ли те люди которые будут ее потом использовать найти все те "самые современные" технологии и тем самым обеспечить работоспособность всей системы в целом. Вот над чем стоит действительно задуматься.
Хотя с другой стороны вполне возможно если мы будем писать эту систему пол года/год, тогда вполне возможно большинство тех новх технологий, задествованных в данном проекте будут уже доступны большинству.

По теме: если будем делать свой класс для работы с БД, в нем неплохо было бы использовать SQL шаблоны, чтобы не мучиться с обработкой передаваемых данных.
Т.е. к примеру у нас есть такой SQL шаблон:
Код

insert into table_name (id, name, mail, www, zipcode, state, etc) values(NULL, %{1 s}, %{2 s}, %{3 s}, %{4 i}, %{5 s}, %{6 s})


А выполнение SQL запроса будет выглядеть примерно следующим образом:

Код

$dbh->sendQuery($sql, $name, $mail, $www, $zipcode, $state, $etc);


Как наверное всем стало ясно, %{number type} заменяется на переменную под номером number форматиоуемую согласно типу type.

Что явно позволит избежать не только SQL инъекций.

Автор: Opik 20.6.2005, 22:40
IZ@TOP
Цитата
Я конечно понимаю на счет того почему стоит использовать PDO, но для начала стоит задуматься для кого и для чего мы пишем нашу CMS? Смогут ли те люди которые будут ее потом использовать найти все те "самые современные" технологии и тем самым обеспечить работоспособность всей системы в целом. Вот над чем стоит действительно задуматься.

PHP 5.1 Обновляется каждые 4 часа, сиё значит что баги всё таки фиксятся, что не может не радовать. Можно даже устроить сотрудничество, с каким нить хостом.

Автор: IZ@TOP 20.6.2005, 22:45
Цитата(Opik @ 20.6.2005, 23:40)
Можно даже устроить сотрудничество, с каким нить хостом.

К примеру с Euorohoster.net?

Автор: Рыжий 20.6.2005, 22:54
Цитата(IZ @ 20.6.2005, 18:59)
Я конечно понимаю на счет того почему стоит использовать PDO, но для начала стоит задуматься для кого и для чего мы пишем нашу CMS?

Лучше имхо использовать САМЫЕ новые технологии и самые новые разработки. Проэкт мы ведь делаем на будущее а не на прошлое smile

Автор: Mal Hack 20.6.2005, 22:56
IZ@TOP
а ты уверен что все СУБД воспримут ANCI'99 на 100%
Добавлено @ 22:57
Цитата(PHP @ 20.6.2005, 23:54)
Лучше имхо использовать САМЫЕ новые технологии и самые новые разработки. Проэкт мы ведь делаем на будущее а не на прошлое smile

Нельзя так делать, т.к. нет уверенности что эти техгнологии приживуться.. Надо использовать то, что уже хоть как-то юзается

Автор: Wowa 20.6.2005, 22:59
Цитата(IZ @ 20.6.2005, 21:45)
К примеру с Euorohoster.net?

Конечно можно.

Автор: Рыжий 20.6.2005, 23:39
Mal Hack
Конечно же технологии всегда нужно использовать в меру, но все таки баналные php5 xml+xsl+xslt - это просто обязанность. А мы должны шагнуть еще дальше и перепюнуть все (ведь мы этого хотим?)

Автор: IZ@TOP 20.6.2005, 23:39
С хостингом мы уже решили.
Добавлено @ 23:40
Цитата(PHP @ 21.6.2005, 00:39)
Конечно же технологии всегда нужно использовать в меру, но все таки баналные php5 xml+xsl+xslt - это просто обязанность. А мы должны шагнуть еще дальше и перепюнуть все (ведь мы этого хотим?)

переплюнуть то конечно можно, но здесь по большей части стоит вопрос в рациональности.

Автор: Gold Dragon 21.6.2005, 09:03
Цитата(PHP @ 20.6.2005, 23:39)
А мы должны шагнуть еще дальше и перепюнуть все (ведь мы этого хотим?)

Шагать лучше не дальше, а вногу. Так что создавать CMS на современных тенденциях не гуманно, а вдруг стандарты не пойдут дальше развиваться или так и остануться не востребованными. Да и срок их внедрения очень примерный

Автор: Рыжий 21.6.2005, 10:30
Red Dragon
Тогда шагаем в ногу! smile

Автор: IZ@TOP 21.6.2005, 13:54
Ну если уж на то пошло, то можно использовать такие технологии как XForms. Очень классная штука кстати, правда широкого распространения пока не получила, но АВТОВАЗ уже применяет ее в своих корпоративных решениях.

Автор: Opik 21.6.2005, 14:23
Везде подвели итоги вроде, подведем и тут. PDO имхо самое лучше по производительности и в меру с развитием технологий.

Автор: Opik 22.6.2005, 12:57
PDO можно ставить и на 5.0.4 так что решено - PDO

Автор: DemoCode 29.11.2005, 20:29
Цитата(Pegas @ 18.6.2005, 20:12)
Проще говоря можно будет использользовать непосредственно несколько различных БД для хранения данных


Для этих целей, я обычно пользуюсь классом adodb - очень удобный ИМХО.
Вот ссылка: http://adodb.sourceforge.net/#download

Цитата
В настоящее время поддерживается работа с базами MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere, Informix, PostgreSQL, FrontBase, SQLite, Interbase (Firebird and Borland variants), Foxpro, Access, ADO, DB2, SAP DB и ODBC.


Цитата
Легок в изучении для Windows-программистов, поскольку использует синтаксис близкий к Microsoft ADO.
В отличие от других PHP классов, которые в основном фокусируются только на SELECT-запросах, мы обращаем внимание также на команды вставки (INSERT) и изменения (UPDATE) данных, которые очень быстро могут модернизироваться под потребности различных баз данных. Также существуют методы для обработки дат, конкатенации строк и экранирования строк по правилам различных баз данных.
Система мето-типов построена так, чтоб вы могли быть уверенными, что сохраняемые вами данные, например CHAR, TEXT, STRING, будут одинаковыми для всех баз данных.
Легкая переносимость, потому что все низкоуровневые функции вынесены отдельно и вам нет необходимости вносить изменения в ядро класса.
Переносимость на уровне создания таблиц и индексов.
Контроль работы базы данных и тонкая настройка производительности.
Поддержка сессии на уровне базы данных, поддержка истечения времени сессии и уведомлений.


Меня не разу не подводил этот класс. Может и вам пригодится.


Автор: dm9 1.6.2006, 16:26
Я понимаю, что тема старая, но вставлю всё же своё мнение - может, кого натолкнёт на умные мысли.

Единственный реально продуманный класс для работы с БД, который я видел - PEAR'овский. Он тяжёлый, конечно, но никто не заставляет использовать именно его - можно взять оттуда часть идей и реализовать их самостоятельно.

Все вышеперечисленные классы (включая PDO) не содержат всего того, что реально часто используется и может быть сокращёно с вызова двух-трёх методов до одного.

Например, это
mixed GetValue(string $query) - выбирает первую ячейку первого столбца.
mixed GetRow(string $query) - выбирает первую строку.
boolean RowExists(string $query) - смотрит, выдаёт ли запрос хотя бы одну строку.

Мелочи, но насколько они могут облегчить жизнь...
 

Автор: Opik 3.6.2006, 00:39
dm9, 
string PDOStatement::fetchColumn ( [int column_number] )
Returns a single column from the next row of a result set. 

PDOStatement::nextRowset --  Advances to the next rowset in a multi-rowset statement handle 

Это насчет PDO.
Который меня устраивает на все 100. 

Автор: m1m1n0 9.7.2006, 02:30
Цитата(Opik @ 3.6.2006,  00:39)
Это насчет PDO.
Который меня устраивает на все 100.

Меня тоже устраивало, но не нашел аналога метода mysql_num_rows
Если есть такой, подскажите плз... 

Автор: Vaulter 21.7.2006, 15:18
давайте начнем сначала,
какой должен быть класс?
я так вижу ситуацию, что необходим список функций с четкими аргументами (в смысле.. задокументированными), на котором (списке) будут формироватся уровень
и так
__construct (?)
connect (выбирать сразу БД?)
selectRow($tablename, $tail);
selectCell(%tablename,$query);
selectList($tablename,$query);// выбирает сразу в массив

query($query);//основная фун-я запроса, возврат и все дела с сохранением всякой лабуды, типа ошибок, русурса, или кол-ва записей....... хотя. нах

fetch()
fetchCell() к примеру
free()

report - вот приблуда:
Код


/*----------------------------------------
        report - return report of some query with templates
        params - array of parametrs
    ----------------------------------------*/
    function report($query, $page, & $ttable,& $trow,$tempty="<p>ничего нет</p>",
    $params = array("onpage" => 100, "pagingurl" => "?page=%d" ,/* in format ?mod=some&mode=list&page=%d sprintf */
        "itemvar" => "item",    "reportvar" => "items",        "pagingvar" => "paging", "callback" => null, "pagertype" => "window" ,"pagelinks"=>15 ))
    {//check params array
        if(empty($params['onpage']) || !is_numeric($params['onpage'])) $params['onpage'] = 100;
        if(empty($params['pagelinks']) || !is_numeric($params['pagelinks'])) $params['pagelinks'] =15;//in row//only for window or slider (<prev 1 2 3 4 5 next>)
        if(empty($params['pagingurl'])) $params['pagingurl'] = "?page=%d";
        if(empty($params['itemvar'])) $params['itemvar'] = "item";
        if(empty($params['reportvar'])) $params['reportvar'] = "items";
        if(empty($params['pagingvar'])) $params['pagingvar'] = "paging";
        if(empty($params['pagertype'])) $params['pagertype'] = "window";//can be continuos or simple, complex TODO
        
        
        $tquery = preg_replace("/SELECT\s+(.*)\s+FROM/is","SELECT COUNT(*) FROM",$query);
        $totalitems = $this->selectCell($tquery);

        //------------------------------------------
        //paging CUT :) too huge
        //------------------------------------------

        $itemvar = $params['itemvar'];
        $reportvar = $params['reportvar'];
        $ritems = $this->_query($query);
        if($ritems && $this->_count($ritems))
        {//do report
            while($$itemvar = $this->fetch($ritems))
            {
                if(!empty($params['callback'])) $params['callback']($$itemvar);
                @eval("\$$reportvar .= \"".$trow."\";");
            }
            @eval("\$ret = \"".$ttable."\";");
        }
        else
        {//empty 
            eval("\$ret = \"".$tempty."\";");
        }
        return $ret;
    }


Добавлено @ 15:19 
собственно... тут ктонить есть? smile 

Автор: Sardar 21.7.2006, 15:31
Цитата(Vaulter @  21.7.2006,  14:18 Найти цитируемый пост)
собственно... тут ктонить есть?

Vaulter, а зачем это всё? Есть PEAR:DB, Adodb для PHP4/5 и PDO для PHP5. Свой слой абстракции это лишнее, ИМХО.
 

Автор: Vaulter 21.7.2006, 17:17
Sardar, а хз!
а если нету?
adodb - жуткая штука
PEAR:DB - посмотрим...
PDO - иногда и нету. 

Автор: Wowa 2.9.2006, 00:30
Итак, я склоняюсь к PDO. Opik, твое мнение относительно PDO не поменялось?

Автор: Opik 2.9.2006, 16:44
Wowa, 
нет, полностью его поддерживаю и пропагандирую smile

Автор: Wowa 2.9.2006, 17:04
Opik, значит решили. Используем PDO.

Автор: IZ@TOP 5.9.2006, 14:16
Wowa, будем писать тулзы для удобного формирования SQL запросов? Типа строитель множественных вставок, апдейтов и удаления?

Автор: Opik 5.9.2006, 15:48
IZ@TOP, 
Мне кажется это лишнее.

Автор: Wowa 5.9.2006, 17:42
Цитата(IZ@TOP @  5.9.2006,  13:16 Найти цитируемый пост)
Wowa, будем писать тулзы для удобного формирования SQL запросов? Типа строитель множественных вставок, апдейтов и удаления? 


Хм.. Имхо от случая зависит, когда-то это удобно, когда-то нет. Если вставка осуществляется из разных мест программы, то конечно лучше в отдельный метод ее вынести. И передавать данные в ввида массива.

А принимать так:

Код

function test($data=array()) {

$sql="INSERT INTO table (test, test2) VALUES ('{$data['test']}', '{$data['test']}')";
$dbh->query($sql); // Ну, это через PDO сделаем

}

Автор: Opik 5.9.2006, 18:38
Wowa, 
Такой отрывок кода специфичен для определенных модулей и выносить такое в драйвер я считаю лишним.

Автор: Wowa 5.9.2006, 18:43
Цитата(Opik @  5.9.2006,  17:38 Найти цитируемый пост)
Такой отрывок кода специфичен для определенных модулей и выносить такое в драйвер я считаю лишним. 

конечно. В драйвер это выносить не стоит.

Автор: IZ@TOP 6.9.2006, 10:32
Ребята! Вы меня по моему не совсем правильно поняли! 
Допустим, мы имеем массив из формы:

Код

$_POST['user'] = array(
    'user_first_name' => 'Arthur',
    'user_last_name' => 'Bier',
    'user_mail' => 'izatop <at> mail [dot] ru',
);


Нам нужно внести эту запись в базу. Как же мы поступим? Напишем код вручную:

Код

$sql = "INSERT user_table INTO (`user_first_name`, `user_last_name`, `user_mail`) 
VALUES(?,?,?)";
$dbh->bindParam($_...);
$dbh->bindParam($_...);
$dbh->bindParam($_...);
...


Или же исполним один простой метод - конструктор SQL запросов:

Код

$sql = WebDbMySqlUtil::sqlMakeInsert('user_table', $_POST, 'primary_field');
$dbh->query($sql);

И это в простейшем случае. Может ведь статься что вставок или апдейтов за раз нужно сделать множество для одной табоицы. И будем дублировать много кода, прогоняя в цикле к примеру составление SQL'я? А можно ведь обойтись вызовом всего одного метода!

Автор: Wowa 6.9.2006, 10:44
IZ@TOP, мне кажется. что довольно редко надо производить вставку того, что пришло без изменений.. или же без какого-то доп. поля.

Автор: Opik 6.9.2006, 11:08
IZ@TOP, 
Это как раз в тему о MVC.

Но на примере твоего кода, твой "идеал":
Код

$sql = WebDbMySqlUtil::sqlMakeInsert('user_table', $_POST, 'primary_field');
$dbh->query($sql);

вместо:
Код

$sth = $dbh>prepare("INSERT user_table INTO (`user_first_name`, `user_last_name`, `user_mail`) VALUES(?,?,?)");
$sth->execute($_POST['user']);


Как видишь, никакого 
Цитата

много кода

здесь нет, другое дело если меняется структура и её нужно везде менять, это да, но для этого я и предложил MVC паттерн.

Автор: IZ@TOP 6.9.2006, 12:04
Цитата(Wowa @  6.9.2006,  11:44 Найти цитируемый пост)
IZ@TOP, мне кажется. что довольно редко надо производить вставку того, что пришло без изменений.. или же без какого-то доп. поля. 

В смысле? А как на счет конструктора условий? Я думаю что это очень полезная вещь.
Ладно, я то в либы добавлю, а там уж кому как, а я буду использовать)

Добавлено @ 12:07 
Opik, Не забывай, намного быстрее сделать множественную вставку, нежели делать их 30 раз подряд. В любом случае, мне кажется что несколько удобнее, и я бы еще даже добавил: сокращает время на отладку SQL запросов, так как конструктор не способен забыть вставить скобку, кавычку или запятую.

Автор: Wowa 6.9.2006, 12:12
Цитата(IZ@TOP @  6.9.2006,  11:04 Найти цитируемый пост)
Opik, Не забывай, намного быстрее сделать множественную вставку, нежели делать их 30 раз подряд.

имхо очень редко множественные ставки нам нужны будут.

Автор: Opik 6.9.2006, 12:18
IZ@TOP, 
Цитата(IZ@TOP @  6.9.2006,  11:04 Найти цитируемый пост)
Opik, Не забывай, намного быстрее сделать множественную вставку, нежели делать их 30 раз подряд

Ммм, поясни?

Автор: IZ@TOP 6.9.2006, 12:39
Вполне возможно что я незнаю всех возможностей PDO, но:

Код

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
foreach($_POST['inserts'] as $key => $insert)
    $stmt->execute($insert);


В данном случае происходит вставки раз за разом выполняя запрос.
Есть множественные вставки, которые представляют из себя VALUES через запятую:
Код

...(:name, :value), (:name, :value), (:name, :value), (:name, :value)...

Должен сказать что это работает гораздо быстрее. И как я уже сказал, на уровне конструктора мы сокращаем время на просмотр SQL ошибок которые появляются из-за опечаток в коде.

Добавлено @ 12:40 
Цитата(Wowa @  6.9.2006,  13:12 Найти цитируемый пост)
имхо очень редко множественные ставки нам нужны будут. 

Я опять цитирую "и я бы еще даже добавил: сокращает время на отладку SQL запросов, так как конструктор не способен забыть вставить скобку, кавычку или запятую."

Автор: Opik 6.9.2006, 12:41
А я что то различия не нашел, между моим кодом и твоим, разве что у тебя в цикле, у меня последовательно, тем более у тебя ошибка smile)

Автор: IZ@TOP 6.9.2006, 13:11
Opik, это пример а не ошибка. Это и есть экономия на отклике базы при отправке пакетов. У тебя будут каждый раз отправляться а у меня один раз и сама вставка будет быстрее.

Автор: Opik 6.9.2006, 13:14
IZ@TOP, 
Объясни мне в чем отличие:
Код

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
foreach($_POST['inserts'] as $key => $insert)
    $stmt->execute($insert);

от
Код

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->execute($array1);
$stmt->execute($array2);
$stmt->execute($array3);


В плане последовательности и скорости вставки?

Автор: IZ@TOP 6.9.2006, 16:20
Opik, 
Цитата(IZ@TOP @  6.9.2006,  13:39 Найти цитируемый пост)
код PHP
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
foreach($_POST['inserts'] as $key => $insert)
    $stmt->execute($insert);

В данном случае происходит вставки раз за разом выполняя запрос.


Это я писал пример с PDO.  А разница с твоим примером в том, что $array1, $array2 тон плохого кода - это раз, а если ты не знаешь сколько записей тебе нужно вставить, что и имелось ввиду в данном случае, то естественно цикл. Если же использовать конструктор, мы за один запрос вставляем все пришедшие к нам записи!

Прям разжевывать все нужно! Ей богу!  smile 

Opik, ты знаешь чем отличаются вставки

Код

INSERT INTO `table` VALUES ('a',3,3,1);
INSERT INTO `table` VALUES ('a',4,4,1);
INSERT INTO `table` VALUES ('a',5,5,1);
INSERT INTO `table` VALUES ('a',6,6,1);
INSERT INTO `table` VALUES ('a',7,7,1);
INSERT INTO `table` VALUES ('a',8,8,1);
INSERT INTO `table` VALUES ('b',2,10,1);
INSERT INTO `table` VALUES ('b',2,11,0);
INSERT INTO `table` VALUES ('b',4,12,0);
INSERT INTO `table` VALUES ('b',4,13,1);
INSERT INTO `table` VALUES ('b',6,14,1);
INSERT INTO `table` VALUES ('b',11,16,0);
INSERT INTO `table` VALUES ('b',20,17,1);
INSERT INTO `table` VALUES ('b',20,18,0);
INSERT INTO `table` VALUES ('b',20,19,0);


и

Код

INSERT INTO `table` VALUES ('a',3,3,1), ('a',4,4,1), ('a',5,5,1), ('a',6,6,1), ('a',7,7,1), ('a',8,8,1), ('b',2,10,1), ('b',2,11,0), ('b',4,12,0), ('b',4,13,1), ('b',6,14,1), ('b',11,16,0), ('b',20,17,1), ('b',20,18,0), ('b',20,19,0);

?

Автор: Opik 6.9.2006, 17:26
IZ@TOP, 
Я понял, что ты имел в виду, знаю. Но я не понимаю где отличие (в этом плане) в этих 2-ух кусках кода? И давай не будем про тон плохого кода, как я тебе уже писал, твой код тоже никуда не годиться  smile))))
Цитата(IZ@TOP @  6.9.2006,  15:20 Найти цитируемый пост)
Если же использовать конструктор, мы за один запрос вставляем все пришедшие к нам записи!

констуктор?

Автор: Wowa 6.9.2006, 18:03
Спор на пустом месте. Я считаю, что необходимость вставки в одну таблицу нескольких строк - это довольно редкая задача и задача эта будет вряд ли где-то в ядре системы. (ну разве, что создание бэкапа базы и восстановление).

Автор: IZ@TOP 6.9.2006, 18:31
Wowa, уверяю что в административной панели при работе с модулями будет очень много необходимости делать множественные вставки!
И это не спор))) Он просто издевается, притворяясь маленьким несмышленым мальчиком  smile 

Цитата(Opik @  6.9.2006,  18:26 Найти цитируемый пост)
И давай не будем про тон плохого кода, как я тебе уже писал, твой код тоже никуда не годиться

У меня вообще кода не было кроме того что с PDO. Внимание вопрос:
Что быстрее, один запрос к базе данных или 30?

Автор: Wowa 6.9.2006, 18:35
Цитата(IZ@TOP @  6.9.2006,  17:31 Найти цитируемый пост)
Wowa, уверяю что в административной панели при работе с модулями будет очень много необходимости делать множественные вставки!

Несколько примеров - в студию! smile

Автор: IZ@TOP 6.9.2006, 18:39
Wowa, голосование, тесты, привязка к разделам, привязка типов, жанров и т.п.
Достаточно или продолжить?
ЗЫ  я щас работая над проектом типа афиши, там этого добра ой-ой-ой сколько. 

И кстате, почему 
Цитата(IZ@TOP @  6.9.2006,  13:39 Найти цитируемый пост)
... и я бы еще даже добавил: сокращает время на отладку SQL запросов, так как конструктор не способен забыть вставить скобку, кавычку или запятую." 

На этот момент вообще у всех ноль внимания?

Автор: Opik 6.9.2006, 19:35
Цитата(IZ@TOP @  6.9.2006,  17:39 Найти цитируемый пост)
На этот момент вообще у всех ноль внимания? 

никогда не считал пропущенную запятую большой ошибкой, все правиться за пару секунд


Цитата(IZ@TOP @  6.9.2006,  17:31 Найти цитируемый пост)
Что быстрее, один запрос к базе данных или 30? 

так реч то не об этом.

Автор: Wowa 6.9.2006, 21:36
Цитата(IZ@TOP @  6.9.2006,  17:39 Найти цитируемый пост)
На этот момент вообще у всех ноль внимания? 


Цитата(Opik @  6.9.2006,  18:35 Найти цитируемый пост)
никогда не считал пропущенную запятую большой ошибкой, все правиться за пару секунд

лично я даже запятую пропускаю крайне редко, поэтому это и не аргумент для меня.

Автор: Sardar 7.9.2006, 00:03
Цитата(IZ@TOP @  6.9.2006,  09:32 Найти цитируемый пост)
Или же исполним один простой метод - конструктор SQL запросов:

Млин, а как же обернуть всё это в логику, что бы не сразу со странички формы в базу, а что то подобное:

Код
//пришли новые курсы со страницы, там JS собирает таблицу и каждые 40 секунд отсылает все изменившиеся строки.

//класс Course представляет собой набор всех курсов в базе
//Course::get(id); - достать по ID, не кешируеться
//foreach(Course::select(aray("cdate"=>Date::interval("2006-09-01", "2006-11-01"))) as $course)
//и т.д.

$cu = Course::update(); //открывает транзакцию

foreach($cupd as $upd) { //в $upd лежит Course::updater() - простейший клас умеет править/создавать новые Course обьекты
  //апдейтеры строяться автоматом с инфы присылаемой от пользователя аяксом
  $course = $upd->process($cu); //не делает обращений в БД, собирает апдейты
  //существует ли строка или это новая известно с инфы которую юзеру отослали, 
  //$upd либо даёт команду на insert, либо update.
}

try {
  $cu->commit(); //если надо открываеться фактическая транзакция в БД, поднимаеться шаблон
  //запроса, формируеться запрос, по возможности всё комбинируеться в единый INSERT/UPDATE
} catch(DBAccessException e){....}

Прикол в том что такие классы очень просты, сами устроены по принципу http://pear.php.net/package/DB_DataObject, расшаривают общий код, но пользовать их одно удовольствие потом smile

Нет прямой связи с БД, захотели сделать откат, не меняя публичный API сделали.

P.S. это я к тому что на слое абстракции PEAR: DB/PDO народ сразу логику ставит, делая прямые запросы... тоже можно, но ИМХО не красиво.

Автор: Wowa 7.9.2006, 10:05
Цитата(IZ@TOP @  6.9.2006,  17:39 Найти цитируемый пост)
Wowa, голосование, тесты, привязка к разделам, привязка типов, жанров и т.п.
Достаточно или продолжить?

неа, недостаточно. Во всех перечисленных тобою вещах множественную вставку - редко где придется делать, да и не будет она большой(ну самый максимум 20 строк) и выполняться будет крайне редко. Поэтому тут совершенно очевидно, что должен использоваться тот код, который более понятен потом при разборке будет, тот код - который удобнее разработчику писать.

Автор: IZ@TOP 7.9.2006, 10:12
Цитата(Opik @  6.9.2006,  20:35 Найти цитируемый пост)
так реч то не об этом. 

Речь как раз об этом!

Sardar, как раз об этом я и говорю! Хотя в чистом виде DataObjects я бы использовать не стал, именно тот что PEAR - ибо тормоз, а вот что-то вроде твоего варианта вполне может подойти. Но далее уже с разных точек нужно рассмотреть что к чему.

Автор: IZ@TOP 7.9.2006, 11:12
Цитата(Wowa @  7.9.2006,  11:05 Найти цитируемый пост)
неа, недостаточно. Во всех перечисленных тобою вещах множественную вставку - редко где придется делать, да и не будет она большой(ну самый максимум 20 строк) и выполняться будет крайне редко. Поэтому тут совершенно очевидно, что должен использоваться тот код, который более понятен потом при разборке будет, тот код - который удобнее разработчику писать. 

Хорошо - возьмем программы передач/афишу. Сколько вставок делается за один раз при импорте данных? Лучше 10 раз по 100 чем 1000 раз подряд. По моему действительно глупый спор. Я пытаюсь об оптимизации разработки и уменьшении затрачиваемых ресурсов сервера говорить. По моему на это все же стоит обратить внимание.

Добавлено @ 11:17 
И еще  мне кажется что использовании метадологии DataObjects приведет к тому что добавление одного поля в базе и инпута в шаблон это все что нужно будет сделать для модификации компонента/модуля.

Автор: IZ@TOP 22.9.2006, 13:22
http://forum.vingrad.ru/index.php?act=ST&f=178&t=113059&st=0#entry863339

Автор: Alone 17.10.2006, 11:45
Ребята, я думаю, Вам надо почитать про ORM.

Это спасет отца русской демократии...

Автор: Wowa 21.10.2006, 17:09
Цитата(Alone @  17.10.2006,  10:45 Найти цитируемый пост)
Ребята, я думаю, Вам надо почитать про ORM.

Ты имеешь ввиду http://en.wikipedia.org/wiki/Object-relational_mapping. Зачем нам объектные базы данных? Кто и что думает по этому поводу? Мне кажется, что не нужно.

Автор: Semenov 23.10.2006, 08:53
Я не вижу смысла в orm. Мое мнение - не нужно.

Автор: korchasa 18.7.2007, 10:30
Цитата(Semenov @ 23.10.2006,  08:53)
Я не вижу смысла в orm. Мое мнение - не нужно.

Сразу после этой фразы можно прекращать разработку. Так как наличие большого объема запросов к данным (пусть даже в виде DBAL) приведет к "костности" системы.

Автор: imm 13.10.2007, 22:27
А уже хоть что-нибудь готово, или вы все спорите?

Автор: SlikJay 24.4.2008, 20:12
http://dklab.ru/lib/DbSimple/
http://dklab.ru/lib/DbSimple/manual.html

Автор: DeamonShan 29.4.2008, 14:27
Предлагаю использовать классы от форума PHPBB очень неплохие классы, у них почти под все БД есть классы... синтаксис один а БД можно использовать любую.. MSSQL, MySQL, PosgreSQL итд итп...

Автор: awers 14.2.2009, 16:02
Немного работы над ошибками провести и юзать сие:
Код

<?php
class M_Core_DB{
    static private $instance = null;
    static function getInstance($params = false){
        if (self::$instance == null){
            self::$instance = new M_Core_DB($params);
        }
        return self::$instance;
    }
    public $handler = null;
    protected $stmt = null;
    protected $keys = array();
    protected $meta = null;
    public function __construct($params = false){
        if ($params) $this->connect($params);
    }

    public function connect($params){
        if (!$params) throw new Exception('Params error');
        if (!$this->handler = new mysqli($params['host'],$params['login'],$params['password'],$params['db'])) throw new Exception(mysqli_error());
        if (array_key_exists('encoding',$params)) $this->query("set names ".$params['encoding']); else $this->query("set names UTF8");
    }
    
    public function query($query, $params = false){
        $this->stmt = $this->handler->prepare($query);
        if (!$this->stmt){
            throw new Exception(mysqli_error($this->handler)."\n\n".$query); 
        }
        if ($params){
            if (!is_array($params)) $params = array($params);
            array_unshift($params, str_repeat('s', count($params)));
            call_user_func_array(array($this->stmt, 'bind_param'),$params);
        }
        $this->stmt->execute();
        $this->stmt->close();
    }
    
    
    public function _execute($query,$params = false){
        $this->stmt = $this->handler->prepare($query);
        if (!$this->stmt){
            throw new Exception(mysqli_error($this->handler)."\n\n".$query); 
        }
        if ($params){
            if (!is_array($params)) $params = array($params);
            array_unshift($params, str_repeat('s', count($params)));
            call_user_func_array(array($this->stmt, 'bind_param'),$params);
        }
        $this->stmt->execute();
        
        $this->meta = $this->stmt->result_metadata();
        $this->keys = array();
        foreach ($this->meta->fetch_fields() as $col) $this->keys[] = $col->name;
        $this->stmt->store_result();
    }
    
    public function fetch(){
        $values = array_fill(0, count($this->keys), null);
        $refs = array();
        foreach ($values as $i => &$f) $refs[$i] = &$f;
        
        call_user_func_array(array($this->stmt, 'bind_result'),$values);
        $retval = $this->stmt->fetch();
        if (!$retval){
         $this->stmt->reset();
         return $retval;
        }
        return array_combine($this->keys, $values);
    }
    
    public function fetchAll($query,$params = false){
        $this->_execute($query,$params);
        
        $data = array();
        while ($row = $this->fetch()){
            $data[] = $row;
        }
        return $data;
        
    }
    
    public function fetchOne($query, $params = false){
        $this->_execute($query,$params);
        
        $this->stmt->bind_result($result);
        $this->stmt->fetch();
        $this->stmt->reset();
        return $result;
    }
    
    public function num_rows(){
        return $this->stmt->num_rows();
    }
    
    public function lastInsertId(){
        return $this->handler->insert_id;
    }
}


Одно точно - юзать стоит именно mysqli. И сторонние либы нафиг нафиг. 

Автор: Wowa 14.2.2009, 16:28
Цитата(awers @  14.2.2009,  15:02 Найти цитируемый пост)
Одно точно - юзать стоит именно mysqli. И сторонние либы нафиг нафиг.  

можешь пояснить почему?

Автор: awers 14.2.2009, 16:52
быстро, современно, никаких mysql_real_escape_string и пр.

Добавлено через 4 минуты и 16 секунд
На счёт стабильности - я на этом классе за прошлый год три с половиной десятка сайтов запустип. Нареканий пока никаких. Жизнеспособно )

Автор: IZ@TOP 27.2.2009, 16:06
Цитата(awers @  14.2.2009,  17:52 Найти цитируемый пост)
быстро, современно, никаких mysql_real_escape_string и пр.

Добавлено через 4 минуты и 16 секунд
На счёт стабильности - я на этом классе за прошлый год три с половиной десятка сайтов запустип. Нареканий пока никаких. Жизнеспособно ) 


Ну, как бы escape_string там тоже есть.
На счет работоспособности - обкатано на продакшене высоконагруженного проекта. Однако, сам класс mysqli все равно прикрыт оболочкой и моделькой. Напрямую никогда не используется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)