 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
 |
|
 |
12-14-2008, 10:17 AM
|
#1 (permalink)
|
|
The Contributor
Join Date: Sep 2008
Location: Miami
Posts: 39
Thanks: 7
|
Stupid OOP question
How would I make a class and object for the following string.
$databse->connect('host','username','password');
$databse->select(dbname);
Sorry for the hassel.
|
|
|
12-14-2008, 01:37 PM
|
#2 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
PHP Code:
class database { public function connect($host, $username, $password) { mysql_connect($host, $username, $password); return $this; }
public function select($db) { mysql_select($db); return $this; } }
$databse = new database(); $databse->connect('host', 'username', 'password')->select('dbname');
Just a quick example to illustrate the idea of how to accomplish this.
__________________
|
|
|
|
|
The Following User Says Thank You to Tanax For This Useful Post:
|
|
12-18-2008, 10:47 AM
|
#3 (permalink)
|
|
The Wanderer
Join Date: Dec 2008
Location: Russia, Moscow
Posts: 14
Thanks: 0
|
my realization
PHP Code:
<?php
class Database
{
/**
* Рузультат SQL-операции в виде ресурса.
*
* @var resource
* @access private
*/
private $result = null;
/**
* Параметры подключения к серверу MySQL.
*
* @var array()
* @access private
*/
private $dbParams = array();
/**
* Текущая БД.
*
* @var string
* @access private
*/
private $current_base = null;
/**
* Ссылка соединения с БД.
*
* @var resource
* @access private
*/
private $lnk = null;
/**
* Строка SQL-запроса.
*
* @var string
* @access private
*/
private $query = null;
/**
* Массив со всеми запросами.
* Предназначен для вывода в процессе отладки.
*
* @var array
* @access private
*/
private static $needs = array();
/**
* Массив имен полей запрошенной таблицы.
* @var array
* @access private
*/
private static $list_fields = array();
/*
* Объект этого класса.
*/
private static $instance;
public static function getInstance()
{
if (!self::$instance)
{
$class = __CLASS__;
self::$instance = new $class();
}
return self::$instance;
}
/**
* Конструктор класса.
*
* @access public
* @param void
* @return void
*/
public function __construct()
{
$this->connect();
}
/**
* Соеденение с базой данных MySQL.
* Метод устанавливает соеденение,
* выбирает БД, устанавливает нужную кодировку.
*
* @access private
* @param void
* @return void
*/
private function connect()
{
if (!is_resource($this->lnk))
{
if (!$this->lnk = @mysql_connect(DB_SERVER,
DB_USER,
DB_PASSWORD
))
{
throw new Exception('Ошибка подключения к СУБД.');
}
$this->setCurrentDb(DB_DATABASE);
$this->query('SET NAMES cp1251');
/*$this->query("set character_set_client='cp1251'");
$this->query("set character_set_results='cp1251'");
$this->query("set collation_connection='cp1251'");*/
}
}
/**
* Устанавливает новую БД {@link $current_base}.
*
* @access public
* @param string $current_base имя базы данных
* @return void
*/
public function setCurrentDb($ndb)
{
$this->current_base = $ndb;
if (!mysql_select_db($this->current_base, $this->lnk))
{
throw new Exception('Невозможно выбрать базу данных: '.mysql_error());
}
}
/**
* Выполняет SQL-запрос.
*
* Результатом будет либо возвращённое булево значение,
* либо объект класса {@link DB_MysqlStatement()}.
*
* Метод принимает обязательный параметр - SQL-запрос и, в случае наличия,
* любое количество аргументов - значения placeholder-ов.
* Метод использует технологию placeholder-ов - для вставки данных в строку SQL-запроса используются
* специальные маркеры, а сами данные передаются "позже".
* Данные, прошедшие через систему placeholder-ов,
* экранируются специальными функциями экранирования,
* в зависимости от типа сравнения (см. далее). Т.е. вам нет
* необходимости заключать переменные в функции
* экранирования типа {@link mysql_escape_string()}.
*
* Маркер обычного сравнения: "?" (знак вопроса) - применяется для любого вида поиска,
* за исключением LIKE-поиска.
* Маркер поиска для LIKE-запросов: "?!" (знак вопроса после которого идёт восклицательный знак) -
* применяется исключительно для LIKE-запросов.
*
* Примеры:
* $myDB->query('SELECT ... FROM ... WHERE id=? AND name=`?`', $id, $user_name);
* Здесь значения переменых $id и $user_name будут обработаны
* функциями экранирования {@link mysql_escape_string()},
* что обезопасит приложение от SQL-инъекций.
* Тогда как в этом примере:
* $myDB->query("SELECT ... FROM ... WHERE `name` LIKE '%?!%'", $name);
* Значение переменой $name будет обработано специальной функцией экранирования для
* LIKE-запросов {@link escape_like()}, что обезопасит приложение от SQL-инъекций.
*
* @access public
* @param string строка SQL-запроса
* @param mixed подставляемые значения для placeholder-ов.
* @return mixed Возвращает либо bool, либо объект класса {@link DB_MysqlStatement()}.
*/
public function query()
{
$this->connect();
$c = func_num_args();
$arg_list = func_get_args();
// Если аргументов в функцию, не переданно, возвращаем FALSE.
if (!$c) {
return false;
}
// Ссылка на запрос.
$q = &$arg_list[0];
$q = str_replace("%", "%%", $q);
// Массмв, в который будем записывать placeholder's
// в порядке появления их в строке.
$ph = array();
// Новый запрос, после обработки нижестоящим кодом.
$nq = '';
$strlen = strlen($q);
// Парсим запрос, по символам.
for ($i=0; $i<$strlen; $i++)
{
// placeholder обычного сравнения - "?".
if ($q[$i]=='?' && (isset($q[$i+1]) && $q[$i+1]!='!' OR !isset($q[$i+1])))
{
$nq .= '%s';
$ph[] = '?';
}
// placeholder для LIKE-поиска - "?!".
else if ($q[$i]=='?' && (isset($q[$i+1]) && $q[$i+1]=='!'))
{
$nq .= '%s';
$ph[] = '?!';
$i++;
}
// это обычный символ.
else {
$nq .= $q[$i];
}
}
$q = $nq; // тут в действительности присваиваем значение $arg_list[0]
$w = 0;
foreach ($arg_list as $k=>$v)
{
// Если значение пусто или это цифра, то никаких escape не делаем.
if (is_int($v) || empty($v)) {
continue;
}
// k = 0 - это всегда SQL-запрос, поэтому эскейпить его не нужно!
if ($k === 0) {
continue;
}
// Это placeholder обычного сравнения.
if ($ph[$w] == '?') {
$arg_list[$k] = mysql_real_escape_string($v, $this->lnk);
}
// Это placeholder поиска LIKE.
else if ($ph[$w] == '?!') {
$arg_list[$k] = $this->escape_like($v);
}
$w++;
}
// Формируем строку SQL-запроса.
$this->query = call_user_func_array('sprintf', $arg_list);
$this->result = mysql_query($this->query, $this->lnk);
if (!$this->result)
{
throw new Exception('MySQL: '.mysql_error().'<br>Ошибка в запросе: <code>'.$this->query.'</code>');
}
self::$needs[] = $this->query;
if (is_resource($this->result))
{
$res = new DB_MysqlStatement($this->lnk);
$res->setResult($this->result);
return $res;
}
return $this->result;
}
/**
* Возвращает id, сгенерированный предыдущей операцией INSERT.
*
* @access public
* @param void
* @return int
*/
public function getInsertId()
{
return mysql_insert_id($this->lnk);
}
/**
* Возвращает количество рядов в результате.
* Эта команда верна только для операторов SELECT.
*
* @access public
* @param void
* @return int
*/
public function getNumRows()
{
return mysql_num_rows($this->result);
}
/*
* Получает количество рядов,
* задействованных в предыдущей MySQL-операции.
* Возвращает количество рядов,
* задействованных в последнем запросе INSERT, UPDATE или DELETE.
* Если последним запросом был DELETE без оператора WHERE,
* все записи таблицы будут удалены, но функция возвратит ноль.
*
* @access public
* @param void
* @return int
*/
public function getAffectedRows()
{
return mysql_affected_rows($this->lnk);
}
/**
* Возвращает экранированную строку для placeholder-а поиска LIKE.
* Данный метод вызывается методом {@link query()} для экранирования переменных,
* которые используются в SQL-операторе поиска LIKE (см. описание метода {@link query()}).
* Описание замены переменых для LIKE-поиска см. на http://phpfaq.ru
*
* @access public
* @param string $var строка в которой необходимо экранировать спец. символы
* @param string $chars набор символов, которые так же необходимо экранировать.
* По умолчанию экранируются следующие символы: "'"%_\\"
* @return string
*/
public function escape_like($var, $chars = "%_\\")
{
if ($chars)
{
$var = addCslashes($var, $chars);
}
$var = mysql_real_escape_string($var, $this->lnk);
return $var;
}
/**
* Закрывает MySQL-соединение.
*
* @access private
* @param void
* @return void
*/
private function close()
{
if (is_resource($this->lnk)) {
@mysql_close($this->lnk);
}
}
/**
* Деструктор, вызывающий $this->close()
*
* @access public
* @param void
* @return void
*/
public function __destruct()
{
$this->close();
}
/**
* Возвращает MySQL-запрос.
* Возвращает строковой параметр -
* последний выполненный MySQL-запрос.
*
* @access public
* @param void
* @return string последний выполненный MySQL-запрос
*/
public function getQueryString()
{
return $this->query;
}
/**
* Возвращает массив $this->querys
*
* @access public
* @param void
* @return array
*/
function getNeeds()
{
return self::$needs;
}
/**
* Возвращает id, сгенерированный предыдущей операцией INSERT.
*
* @access public
* @param void
* @return int
*/
public function getLastInsertId()
{
return mysql_insert_id($this->lnk);
}
/**
* Возвращает массив имен полей таблицы $table
* текущей базы и их значений по умолчанию.
*
* @access public
* @param string имя таблицы
* @return array
*/
public function getListFields($table)
{
if (!isset(self::$list_fields[$table]))
{
$fields = mysql_list_fields($this->current_base, $table, $this->lnk);
$columns = mysql_num_fields($fields);
for ($i = 0; $i < $columns; $i++)
{
$obj = mysql_fetch_field($fields, $i);
switch ($obj->type)
{
case 'int':
$val = (int)$obj->def;
continue;
case 'datetime':
case 'date':
$val = '';
continue;
case 'string':
case 'blob':
$val = (string)$obj->def;
continue;
}
self::$list_fields[$table][$obj->name] = $val;
}
}
return self::$list_fields[$table];
}
/*
* Возвращает объект результата SQL запроса на выборку $limit случайных
* строк из таблицы $table_name. В таблице должен быть определён
* первичный ключ $primary_name.
*/
public function getUnique($primary_name, $table_name, $limit = 1)
{
$sql = '
SELECT
*
FROM
`'.$table_name.'`
WHERE
`'.$primary_name.'` >= (
SELECT
FLOOR(MAX('.$primary_name.') * RAND())
FROM
`'.$table_name.'`
)
ORDER BY
`'.$primary_name.'`
LIMIT 1';
return $this->query($sql);
}
}
/**
* Класс работы с результатом MySql.
*/
class DB_MysqlStatement
{
/**
* Ссылка соединения с БД.
* @var resource
* @access private
*/
private $lnk = null;
/**
* Рузультат SQL-операции в виде ресурса.
* @var resource
* @access private
*/
private $result = null;
/**
* Конструктор класса.
* @access public
* @param void
* @return void
*/
public function __construct($lnk)
{
$this->lnk = $lnk;
}
function setResult($res)
{
$this->result = $res;
}
function getResult()
{
return $this->result;
}
function fetch_assoc()
{
return mysql_fetch_assoc($this->result);
}
function fetch_row()
{
return mysql_fetch_row($this->result);
}
function fetch_assoc_array()
{
$array = array();
while(($row = mysql_fetch_assoc($this->result)) !== FALSE)
{
$array[] = $row;
}
return $array;
}
function fetch_row_array()
{
$array = array();
while(($row = mysql_fetch_row($this->result)) !== FALSE)
{
$array[] = $row;
}
return $array;
}
public function getOne()
{
$row = mysql_fetch_row($this->result);
return $row[0];
}
}
?>
exemple:
PHP Code:
$db = Database::getInstance();
$res = $db->query('INSERT INTO table SET id = ?, value = ?', $id, $value); // $id, $value handler of mysql_real_escape_string
while ($row = $res->fetch_assoc())
{
print_r($row);
}
|
|
|
|
12-18-2008, 12:15 PM
|
#4 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Wow. You need to come up with some better variable names!
$nk
$k
$ph
etc.
But you have descriptions, so that's good..
But we can't understand them 
__________________
|
|
|
|
03-17-2009, 02:12 AM
|
#5 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
Wow. You need to come up with some better variable names!
$nk
$k
$ph
etc.
But you have descriptions, so that's good..
But we can't understand them 
|
Well, perhaps it makes a lot more sense to him in Russian!!
|
|
|
|
03-17-2009, 07:42 AM
|
#6 (permalink)
|
|
The Wanderer
Join Date: Dec 2008
Location: Russia, Moscow
Posts: 14
Thanks: 0
|
Quote:
Originally Posted by allworknoplay
Well, perhaps it makes a lot more sense to him in Russian!!
|
No, it`s acronyms.
$ph - placeholders
$nq - new query
$q - query
etc
|
|
|
|
|
The Following User Says Thank You to triumvirat For This Useful Post:
|
|
03-17-2009, 08:14 AM
|
#7 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
You might consider doing away with the acronyms and just using the descriptive names. Not only does it make your code more readable in general, but if you get distracted from a project for a couple weeks, it saves a lot of time figuring out what you were up to.
I know I'm not the norm, but I've used cryptic variables in the past that I blanked on within two days. In a large code base, this can cause a lot of back tracing and head scratching before you catch up with where you were at.
|
|
|
|
03-17-2009, 08:19 AM
|
#8 (permalink)
|
|
The Wanderer
Join Date: Dec 2008
Location: Russia, Moscow
Posts: 14
Thanks: 0
|
Ok! ;)
=====
|
|
|
|
03-17-2009, 03:45 PM
|
#9 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by triumvirat
No, it`s acronyms.
$ph - placeholders
$nq - new query
$q - query
etc
|
ahhh gotchya....it was just a joke anyways...regarding the Russian thing....
I've always wanted to learn Russian..and Chinese....and Japanese...and Spanish....
Quote:
Originally Posted by delayedinsanity
You might consider doing away with the acronyms and just using the descriptive names. Not only does it make your code more readable in general, but if you get distracted from a project for a couple weeks, it saves a lot of time figuring out what you were up to.
I know I'm not the norm, but I've used cryptic variables in the past that I blanked on within two days. In a large code base, this can cause a lot of back tracing and head scratching before you catch up with where you were at.
|
Agreed. If you can describe your variables correctly, then they would be self commenting...my achille heals is when I'm in front of the computer screen for way too long and I start to get lazy with the naming schemes...because I just want to get the results so I can call it a day...
|
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|