Написал класс, нужна критика

Статус
В этой теме нельзя размещать новые ответы.

terkin

Мой дом здесь!
Регистрация
9 Дек 2006
Сообщения
513
Реакции
200
Начал учить ООП, до этого всегда писал функциями, решил всё же начать использовать все прелести ООП и написал класс для работы с mysql, хотелось бы услышать вашу критику, советы по оптимизации ну и если есть то мои ошибки.
PHP:
class mysql_class
{
	var $server='localhost';
	var $login;
	var $pass;
	var $bd;
	var $counter=0;
	public function __construct($login,$pass,$server,$bd)
	{
		$this->server=$server;
		$this->login=$login;
		$this->pass=$pass;
		$this->bd=$bd;
	}
	function connect()
	{
		mysql_connect($this->server, $this->login, $this->pass) or die ("Could not connect to $this->server");
		mysql_select_db ($this->bd)  or die ("Could not select $this->bd");

	}

	function query($query)
	{
		$w=mysql_query($query) or die(mysql_error().'<br><textarea rows=5 cols=50>'.$query.'</textarea>');
		$this->counter++;
		return $w;
	}
	function query_counter()
	{
		echo 'Было выполнено '.$this->counter.' запросов к базе данных.';
	}
	function __destruct() {
        $this->server;
        $this->login;
		$this->pass;
		$this->bd;
		mysql_close();
    }
    
}

Пример работы с классом:

PHP:
$mysql=new mysql_class('root','','localhost','top');
$mysql->connect();
$a="SELECT *  FROM robots";
$mysql->query($a);
$mysql->query_counter();
 
ну теперь вопрос :)
как ты собираешься им пользоваться из других классов (к примеру в одном месте тебе надо получить список пользователей и совсем другом новости), создавая соединение заново?

ну и тогда добавляй что то вроде облегченного insert и update :)
 
ООП реализации php4.. лучше сразу на ооп-php5 писать, вместо var - область использования

например...
PHP:
class database {
	private $db;
	public $sql;
	public $result;
	function setQuery($sql,$offset=0,$limit=0) {
		$this->sql = $sql . (($limit)?" LIMIT $offset, $limit":"");
		$this->result = @mysql_query($this->sql,$this->db) or die($this->mysql_err());
	}
	function insert_id() {
		return mysql_insert_id($this->db);
	}

...

 - - - 

...
	
	function __construct() {
		global $config;
		$this->db = @mysql_connect($config['m_host'], $config['m_user'], $config['m_pass']) or die ($this->mysql_err());
		@mysql_select_db($config['m_db']) or die ($this->mysql_err());
		@mysql_query('SET NAMES '.$config['m_cp'],$this->db) or die ($this->mysql_err());
	}
	function __destruct() {
		@mysql_close($this->db) or die ($this->mysql_err());
	}
	function mysql_err(){
		global $config;
		if ($config['debug']) {
			echo $this->sql .'<br>';
			die (mysql_error());
		}
	}
}
 
2terkin
PHP:
function __destruct() { 
        $this->server; 
        $this->login; 
        $this->pass; 
        $this->bd; 
        mysql_close();
Не понял зачем эти 4 строчки
PHP:
$this->server; 
$this->login; 
$this->pass; 
$this->bd;
PHP:
 mysql_connect($this->server, $this->login, $this->pass) or die ("Could not connect to $this->server");
mysql_connect() - возвращает хендл соединения, думаю его тоже стоит использовать... Иначе возможно, что когда создашь два объекта и сделаешь дестрой первого, он убъет соединение второго... :D
Если не исользуешь подавление ошибок, не забудь убрать вывод их в отлаженных скриптах ;)
Конструкция or не самая быстрая.. Возможно, лучше использовать (но лучше провести тест)
PHP:
mysql_query('bla-bla')===FALSE?$this->log[]=mysql_error($this->mysql_handle):'';
 
Советую взять некоторый функционал из моего класса. Правда, тут присутствует некоторый хаос с другими связками - ибо из ядра класс...


PHP:
<?php
class mysql implements Interface_class
{
	private		$db_user;
	private		$db_pass;
	private		$db_host;
	private		$db_name;
	
	private		$debug;
	public		$dbh;
	
	function __construct()
	{	
		
		$this->debug = $_SESSION['obj']['debug'];
		
		$this->db_host = (defined('DB_HOST'))?DB_HOST:$this->debug->add_err(ERR_DBHOST_NOT_DEFINED.ERR_CHECK_CONFIG,CRITICAL);
		$this->db_user = (defined('DB_USER'))?DB_USER:$this->debug->add_err(ERR_DBUSER_NOT_DEFINED.ERR_CHECK_CONFIG,CRITICAL);
		$this->db_pass = (defined('DB_PASS'))?DB_PASS:$this->debug->add_err(ERR_DBPASS_NOT_DEFINED.ERR_CHECK_CONFIG,CRITICAL);
		$this->db_name = (defined('DB_NAME'))?DB_NAME:$this->debug->add_err(ERR_DBNAME_NOT_DEFINED.ERR_CHECK_CONFIG,CRITICAL);
	}
	
	function __destruct()
	{
	}
	public function connect()
	{	$this->dbh = mysql_connect($this->db_host,$this->db_user,$this->db_pass) or $this->debug->add_err(ERR_DB_NOT_CONNECTED,CRITICAL);
		(mysql_select_db($this->db_name, $this->dbh))?$this->debug->add_err(DB_SELECTED,INFO):$this->debug->add_err(ERR_DB_NOT_SELECTED,CRITICAL);
		
//		$this->execute('SET charset utf8',  null,null);
//		$this->execute('SET charset cp1251',null,null);
	}
	public function execute($query,$file='index.php',$line=NOT_DEFINED)
	{	$info = ' in file: <b>'.$file.'</b> at line: <b>'.$line.'</b>';
		if(!$this->dbh) {$this->connect();}
		if(!$this->dbh) 
		{	$this->debug->add_err(ERR_DB_NOT_CONNECTED,CRITICAL);
			die(ERR_DB_NOT_CONNECTED);
		}
		
		$result = mysql_query($query) or die(mysql_error());
		($result)?$this->debug->add_err(DB_QUERY_EXECUTED.$info,INFO):$this->debug->add_err(ERR_DB_QUERY_EXEC.$info,CRITICAL);
		return $result;
	}
	public function multi_rows($query, $row_limit=-1,$file='index.php',$line=NOT_DEFINED)
	{	$result = $this->execute(&$query);
		while ($row = mysql_fetch_assoc(&$result) && $row_limit)
		{	$all_rows[] = $row;
			$row_limit--;
		}
		return $all_rows;
	}
	public function one_row($query,$file='index.php',$line=NOT_DEFINED)
	{	$result = $this->execute(&$query);
		return mysql_fetch_assoc(&$result);
	}
	public function multi_rows_assoc($query, $row_limit=-1,$file='index.php',$line=NOT_DEFINED)
	{	$result = $this->execute(&$query,&$file,&$line);
		$i = 0;
		while (($row = mysql_fetch_assoc($result)) && $row_limit)
		{	
			foreach ($row as $key=>$value)
			{	$all_rows[$i++][$key] = $value;
			}
			$row_limit--;
		}
		return $all_rows;
	}	
	
	public function multi_rows_field_assoc($query, $field, $row_limit=-1,$file='index.php',$line=NOT_DEFINED)
	{	$result = $this->execute(&$query,&$file,&$line);
		
		while (($row = mysql_fetch_assoc($result)) && $row_limit)
		{	$all_rows[$row[$field]] = $row;
			$row_limit--;
		}
		return $all_rows;
	}
}

?>
 
Наследовать mysqli, mysqli_stmt намного веселее - дописывай, что хочешь

PHP:
$db = new My_Mysqli(MYSQLI_HOST, MYSQLI_USER, MYSQLI_PASS, MYSQLI_DBNAME);

$records = array();

$q = "...";
$result = $db->query($q);
if ($result) {
	while($r = $result->fetch_assoc())
		$records[] = $r;
	$result->free_result();
}

print_r($records);


class My_Mysqli extends mysqli {
	private $stmts = array();
	private $query_time;
	
	public function query($query, $resultmode = MYSQLI_STORE_RESULT) {
		$start = microtime(1);
		$result = parent::query($query, $resultmode);
		$this->query_time += microtime(1) - $start;
		$this->make_log($query);
		return $result;
	}
	
	public function make_log($query) {
		if (!defined('MYSQL_LOGFILE')) return;
		$str = date('Y-m-d H:m:s') . "\t" . $_SERVER['REMOTE_ADDR'] . "\t" . $query . "\n";
		if ($this->errno)
			$str .= "ERROR: " . $this->errno . ", " . $this->error . "\n";
		if ($this->errno || stripos($query, "insert") !== FALSE ||
					stripos($query, "update") !== FALSE || stripos($query, "delete") !== FALSE) {
			$f = fopen(MYSQL_LOGFILE, 'a');
			fwrite($f,$str);
			fclose($f);
		}
	}
	
	function get_count($table, $where, $id = 'id') {
		 $result = $this->query("SELECT COUNT($id) AS a FROM $table WHERE " . $where);
		 $a = mysql_result($result,0,'a');
		 mysql_free_result($result);
		 return $a;
	}
	
	function get_query_time() {
		return number_format($this->query_time,6)*1000 . "ms";
	}
	
	function get_elements($q) {
    #echo parent;
		$result = $this->query($q);
		if ($this->errno != 0 || $this->affected_rows == 0) return NULL;
		$ret = array();
		while ($row = $result->fetch_assoc())
			$ret[$row['id']] = $row;
		$result->free_result();
		return $ret;
	}
	
	public function mres($q) {
		return $this->real_escape_string($q);
	}
  
  public function stmt_init() {
    $stmt = new My_Mysqli_Stmt($this);
    $this->stmts[] = $stmt;
    return $stmt;
  }
	
	public function close() {
    foreach ($this->stmts as & $stmt)
      if (!$stmt->closed) {
        echo "Error";
        $stmt->close();
      }
    parent::close();
  }
}


class My_Mysqli_Stmt extends mysqli_stmt {
	public $closed = FALSE;
	
	public function test() {
		
	}
	
	public function close() {
		parent::close();
		$this->closed = TRUE;
	}
}
 
зачем такая прелесть нужна?

на пхп нет смысла писать проект по размеру когда нужен ООП.

В смысле когда появляет положительный ефект.

пхп выигрывает когда надо сделат, что простое.

ООП в ПХП это зря потраченое время.

В пхп очень редко нужна mysql_close
Обычно лучше использовать mysql_pconnect
 
Писать класс для работы с БД в PHP следует только в том случае, когда нужно от этой БД абстрагироваться, т.е. получить какую-никакую "кросс-платформенность". Существует множество абстрактных классов для этого ( Для просмотра ссылки Войди или Зарегистрируйся ).
В небольших скриптах в этом нет смысла, т.к.

1)mysql_connect
2)mysql_select_db
3)mysql_query
4)mysql_fetch_array
5)mysql_close
 
Ещё нужно писать функцию не $db->query($q)

А что было что типа $db->addUser($login, $first, $last, $pass);

Так как базы могут отличаться по синтексу.

Но я не вижу причины, почему, если у тебя уже есть ПХП не поставить мускл. ОН самый быстрый и бесплатный.

В 99% это неоправданный гемор.

Если уже такое надо то лучше искать, что уже существуещее.
 
ООП это не панацея, как все считают это. Такие структурные вещи как работа с БД за многое время не изменилось и использование классов только усложнит работу скриптов (на 30%). Да, если проект серъезный без этого никуда, но в обыкновенных проектах структурный подход к написанию только быстрее будет.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху