В своё время возникла необходимость уйти от использования PEAR DB при работе с MySQL (ввиду очевидных причин: прекращение поддержки в последних версиях php, тормознутость итп) но учитывая мегатонны написанного кода начал искать эмулятор. К своему удивлению ничего более менее годного не нашел. Пришлость потратить немного время и нарисовать свой.
В классе реализовывал только те части что использовались в проектах (скорее всего в 99% случаев остальным этого тоже хватит) кому не хватит, думаю, не составит труда дополнить/подправить самим. Поскольку проекты для которых это делалось были давно завершены то дальнейшего развития этот код не получил. Но если кто то что то дополнит или исправит буду не против.
Эмулятор состоит из 2х частей, класса обработки ошибок с возможностью записи их в лог и наследуемого от него класса эмулятора PEAR DB.
Код был успешно протестирован на 2х проектах. Безусловно в коде можно много ещё чего исправить и дополнить но воспринимайте его как начальную точку от которой можно двигаться дальше. Дополнения и правки пожалуйста в личку, на своё усмотрение буду их вносить в исходники.
Надеюсь кому то это пригодится и просьба сильно не пинать, как всё что делается задним числом для того что уже давно пройдено код страдает своими очевидными недостатками. Выкладывая его сюда просто хочу помочь съеэкономить кому то время а не похвастаться его красотой.
Далее по делу:
Класс ошибок:
И далее сам эмулятор DB
Думаю дальнейшие комментарии тут излишни, код не велик и достаточно прост. Но если вопросы возникли готов ответить.
Для начала работы с классом достаточно отключить PEAR DB, включить данный код, создать экземпляр класса DB и переписать функцию connect.
С Уважением Михаил Червоненко.
п.с. Поскольку исходники не велики позволил себе запостить их целиком в текст статьи, опять же это позволит оперативно исправить если будут замечания или пожелания.
В классе реализовывал только те части что использовались в проектах (скорее всего в 99% случаев остальным этого тоже хватит) кому не хватит, думаю, не составит труда дополнить/подправить самим. Поскольку проекты для которых это делалось были давно завершены то дальнейшего развития этот код не получил. Но если кто то что то дополнит или исправит буду не против.
Эмулятор состоит из 2х частей, класса обработки ошибок с возможностью записи их в лог и наследуемого от него класса эмулятора PEAR DB.
Код был успешно протестирован на 2х проектах. Безусловно в коде можно много ещё чего исправить и дополнить но воспринимайте его как начальную точку от которой можно двигаться дальше. Дополнения и правки пожалуйста в личку, на своё усмотрение буду их вносить в исходники.
Надеюсь кому то это пригодится и просьба сильно не пинать, как всё что делается задним числом для того что уже давно пройдено код страдает своими очевидными недостатками. Выкладывая его сюда просто хочу помочь съеэкономить кому то время а не похвастаться его красотой.
Далее по делу:
Класс ошибок:
<?php
/*
* Class: Error
* Progr.: Mikhail Tchervonenko
* Data: 2009-03-04
* EMail: rusmikleATgmailPointCom
* ICQ: 35818796
* Skype: RusMikle
*/
class ERROR
{
var $show_errors =false;
var $stop_after_error =false;
var $error =0;
var $error_message ="";
var $error_messages =false;
var $error_backtrase =false;
var $error_filename = 'error_log/error_log.txt';
// ***********************************
// ***** err_log function start
function err_log($error_text="",$error_backtrase=false)
{
$this->error=1;
$this->error_backtrase = $error_backtrase;
$error_backtrase = $this->backtrace()."\n\r";
$this->error_message = "-----".date("D M j G:i:s T Y").$error_text;
if (is_writable($this->error_filename))
{
if (!$handle = fopen($this->error_filename, 'a'))
{
$ret = false;
}
if (fwrite($handle, "\n\r------\n\r".$this->error_message.$error_backtrase."\n\r-------\n\r") === FALSE)
{
$ret = false;
}
fclose($handle);
$ret = true;
}
if($this->error_backtrase)
$this->error_message .= "\n\r".$error_backtrase;
$this->error_messages[] = $this->error_message;
if($this->show_errors)
echo str_replace("\n\r","<br>",$this->error_message);
if($this->stop_after_error)
exit();
return $ret;
}
// ***********************************
// ***** backtrace function start
function backtrace()
{
$output = "\n\r";
$output .= "Backtrace:\n\r";
$backtrace = debug_backtrace();
foreach ($backtrace as $bt)
{
$args = '';
foreach ($bt['args'] as $a)
{
if (!empty($args))
{
$args .= ', ';
}
switch (gettype($a))
{
case 'integer':
case 'double':
$args .= $a;
break;
case 'string':
$a = substr($a, 0, 64).((strlen($a) > 64) ? '...' : '');
$args .= "\"$a\"";
break;
case 'array':
$args .= 'Array('.count($a).')';
break;
case 'object':
$args .= 'Object('.get_class($a).')';
break;
case 'resource':
$args .= 'Resource('.strstr($a, '#').')';
break;
case 'boolean':
$args .= $a ? 'True' : 'False';
break;
case 'NULL':
$args .= 'Null';
break;
default:
$args .= 'Unknown';
}
}
$output .= "\n\r";
$output .= "file: {$bt['line']} - {$bt['file']}\n\r";
$output .= "call: {$bt['class']}{$bt['type']}{$bt['function']}($args)\n\r";
}
$output .= "\n\r";
return $output;
}
// ***********************************
// ***** getMessage function start
function getMessage()
{
return $this->error_message;
}
}
?>
И далее сам эмулятор DB
<?php
/*
* Class: DB
* Progr.: Mikhail Tchervonenko
* Data: 2009-03-04
* EMail: rusmikleATgmailPointCom
* ICQ: 35818796
* Skype: RusMikle
*/
class DB extends ERROR
{
var $tp ="cms1_";
var $conn =false;
var $counter =0;
// ***********************************
// ***** set_database function start
function set_database($database)
{
$res = mysql_select_db($database,$this->conn);
if(!$res)
{
$this->err_log();
return false;
}
$this->error=0;
return true;
}
// ***********************************
// ***** construct function start
function connect($host="localhost",
$user="root",
$pass="",
$database="",
$table_prefix="st__",
$show_errors = false,
$stop_after_error =false,
$error_backtrase = false,
$error_log_file="error_log/error_log.txt")
{
$this->tp = $table_prefix;
$this->show_errors =$show_errors;
$this->stop_after_error =$stop_after_error;
$this->conn = mysql_connect($host, $user, $pass);
if(!$this->conn)
{
$this->err_log();
return false;
}
if(!$this->set_database($database))
return false;
$this->error=0;
return true;
}
// ***********************************
// ***** destruct function start
function __destruct()
{
if(!empty($this->conn))
@mysql_close($this->conn);
$this->conn = null;
}
// ***********************************
// ***** close function start
function close()
{
if(!empty($this->conn))
@$mysql_close($this->conn);
$rs = null;
$this->error=0;
}
// ***********************************
// ***** query function start
function query($query)
{
$this->error=0;
$ret = mysql_query($query,$this->conn);
if(!$ret)
{
$this->err_log(mysql_error()."\n\rQUERY:"."\n\r".$query);
return false;
}
return $ret;
}
// ***********************************
// ***** fcount function start
function fcount($res)
{
if(!$res)
return 0;
$ret = @mysql_num_fields ($res);
return $ret;
}
// ***********************************
// ***** ecount function start
function ecount($res)
{
if(!$res)
return 0;
$ret = @mysql_num_rows ($res);
return $ret;
}
// ***********************************
// ***** getOne function start
function getOne($sql)
{
if(empty($sql))
{
$this->error=1;
return false;
}
$res = $this->query($sql);
$ret = @mysql_fetch_array($res,MYSQL_NUM);
if(!empty($res))
@mysql_free_result($res);
return $ret[0];
}
// ***********************************
// ***** getRow function start
function & getRow($sql, $ret_type=MYSQL_ASSOC)
{ // MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH
if(empty($sql))
{
$this->error=1;
return false;
}
$this->counter = 0;
$ret=array();
$res = $this->query($sql);
$ret = @mysql_fetch_array($res, $ret_type);
$this->counter = $this->ecount($res);
if(!empty($res))
@mysql_free_result($res);
return $ret;
}
// ***********************************
// ***** getAll function start
function & getAll($sql, $ret_type=MYSQL_ASSOC)
{ // MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH
if(empty($sql))
{
$this->error=1;
return false;
}
$this->counter = 0;
$ret=array();
$res = $this->query($sql);
if(!empty($res))
$this->counter = $this->ecount($res);
if($this->counter>0)
{
while ($row = @mysql_fetch_array($res, $ret_type))
$ret[] = $row;
}
if(!empty($res))
@mysql_free_result($res);
return $ret;
}
// ***********************************
// ***** nextId function start
function nextId($table_name)
{
if(empty($table_name))
return false;
$table_name=strtolower(trim($table_name))."_seq";
$this->query("CREATE TABLE IF NOT EXISTS `".$table_name."` (`id` bigint(20) unsigned) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
$this->query("LOCK TABLES ".$table_name." WRITE");
$id = $this->getOne("SELECT id FROM ".$table_name);
if(empty($id))
{
$id=1;
$this->query("INSERT into ".$table_name." SET id=".$id);
}
else
{
$id++;
$this->query("UPDATE ".$table_name." SET id=".$id);
}
$this->query("UNLOCK TABLES");
return $id;
}
// ***********************************
// ***** iserror function start
// функция существует только для совместимости со старой PEAR библиотекой !!!!
function iserror($result)
{
if(!is_object($result) && !is_array($result) && empty($result))
return true;
else
return false;
}
}// End Class
?>
Думаю дальнейшие комментарии тут излишни, код не велик и достаточно прост. Но если вопросы возникли готов ответить.
Для начала работы с классом достаточно отключить PEAR DB, включить данный код, создать экземпляр класса DB и переписать функцию connect.
С Уважением Михаил Червоненко.
п.с. Поскольку исходники не велики позволил себе запостить их целиком в текст статьи, опять же это позволит оперативно исправить если будут замечания или пожелания.