Jump to content
  • 0

ооп проблема


vvsh
 Share

Question

доброе время суток.

есть класс db

в нем функции query, row

class db {
var $query_id;
function query($query) {
$this->query_id = mysql_query($query);
}
function row() {
return mysql_fetch_array($this->query_id);
}
}

когда в классе show я наследую класс db

и пишу функцию которая выводит информацию

class show extends db {
function data() {
$this->query("SELECT * FROM table");
$num = $this->num();
if($num>0) {
$i = 1;
while($row = $this->row()) {
$this->query("SELECT * FROM table2 WHERE field2 = '$row[field]'");
$nums = $this->num();
$body .= "<a href='$row[field3].html'>$row[field4] [$nums]</a>";
if($i!=$num){
$body .= "<br>";
}
$i++;
}
} else {
$body .= "Пусто";
}
return $body;
}
}

вызываю данную функцию так:

$show = new show;

$show->data();

В этой таблице около 20 записей.

При выводе, мне выводит только так

<a href='1.html'>1 [1]</a>

[0]

хотя должно вывести

<a href='1.html'>1 [1]</a>

<a href='2.html'>2 [2]</a>

<a href='3.html'>3 [3]</a>

и т.д.

как мне сделать так, чтобы выводило как надо?

Edited by vvsh
Link to comment
Share on other sites

  • Answers 51
  • Created
  • Last Reply

Top Posters For This Question

Recommended Posts

  • 0
может мне кто-нибудь поможет решить эту проблему?

Давай все с начала. Представь, что меня до этого здесь не было и я не обзывал тебя пять раз :lol:

В чем суть проблемы, объясни досканально, а не как ты обычно объсняешь — «не работает!!!».

Link to comment
Share on other sites

  • 0

проблема в том, что первый запрос происходит, но в цикле происходит второй запрос, и когда уже цикл продолжается, $this->row равно результату запроса в цикле, а должно быть равно результату запроса перед циклом...

Edited by vvsh
Link to comment
Share on other sites

  • 0

Чем у тебя является класс db ? Является ли он классом для работы с базой данных, или классом для работы с одним запросом?

Если он является классом для работы с базой, то как в нем оформляется ответ от базы, есть ли у него какая-то сущность, которая четко идентифицирует один запрос?

Link to comment
Share on other sites

  • 0

классом для работы с базой.

ответ от базы записывается в переменную $this->query_id, переменная заранее задается в классе var $query_id;

да, запись в переменную query_id.(если я правильно понял...)

Link to comment
Share on other sites

  • 0
классом для работы с базой.

ответ от базы записывается в переменную $this->query_id, переменная заранее задается в классе var $query_id;

да, запись в переменную query_id.(если я правильно понял...)

query_id у тебя содержится в том же классе, что и сама база. Может быть нужно создавать отдельный объект для каждого запроса?

<?php
class cDBQuery implements Iterator, ArrayAccess{
function __construct($sql, $params=NULL, $mode = MYSQL_ASSOC){
if ($params !== NULL) {
if (gettype($params) == 'array') {
foreach($params as &$param){
$param = "'".mysql_escape_string($param)."'";
}
array_unshift($params, $sql);
$sql = call_user_func_array('sprintf', $params);
} else {
$sql = sprintf($sql, "'".mysql_escape_string($params)."'");
}
}
if (cDBQuery::$link){
$this->r = mysql_query($sql, cDBQuery::$link);
if (mysql_errno(cDBQuery::$link)){
throw new Exception("cDBQuery->__construct() : ".mysql_error(cDBQuery::$link));
}
} else {
$this->r = mysql_query($sql);
if (mysql_errno()){
throw new Exception("cDBQuery->__construct() : ".mysql_error());
}
}
$this->length = mysql_num_rows($this->r);
$this->mode = $mode;
$this->current_row = 0;
}
function __destruct() {
mysql_free_result($this->r);
}

/* implements of Iterator */
function valid() {
return $this->current_row < $this->length;
}
function rewind() {
$this->current_row = 0;
$this->seek();
}
function key() {
return $this->current_row;
}
function next() {
$this->current_row++;
}
function current(){
return mysql_fetch_array($this->r, $this->mode);
}

/* implements of ArrayAccess */
function offsetExists($id){
return (((int) $id) < $this->length) && (((int) $id) >= 0);
}
function offsetGet($id){
if ($this->offsetExists($id)) {
if ($this->current_row != $id) {
$this->current_row = (int) $id;
$this->seek();
}
$this->next();
return $this->current();
} else {
return NULL;
}
}
function offsetSet($id, $val){
/* not supported in DBQuery */
}
function offsetUnset($id){
/* not supported in DBQuery */
}

protected function seek(){
if ($this->length)
mysql_data_seek($this->r, $this->current_row);
}

public function getRow(){
if ($this->length)
return mysql_fetch_array($this->r, $this->mode);
else
return array();
}
public function getValue(){
if ($this->length) {
$row = mysql_fetch_row($this->r);
return $row[0];
} else
return NULL;
}
public function getID() {
if (cDBQuery::$link)
$r = mysql_query('SELECT LAST_INSERT_ID()', cDBQuery::$link);
else
$r = mysql_query('SELECT LAST_INSERT_ID()');
$row = mysql_fetch_row($r);
mysql_free_result($r);
return $row[0];
}

public $mode; // mode of return row: MYSQL_ASSOC, MYSQL_NUM or MYSQL_BOTH
public $length; // count of returned rows;
static public $link = NULL; // set you link identifer before use
protected $r;
protected $current_row;
}
?>

Link to comment
Share on other sites

  • 0

Ок, подробнее.

Берешь книгу, садишься за стол, открываешь на первой странице. Начинаешь внимательно читать сверху вниз. Как только замечаешь, что на этой странице текста больше нет, переворачиваешь страницу и начинаешь читать новую. Так пока страницы в книге не закончатся.

Link to comment
Share on other sites

  • 0

твой способ хорош. но есть лучше.

Шаг первый.

берем мануал.

http://floomby.ru/content/lAxTxkenS0/

за качество не ругайте :lol:

Шаг второй. Отрываем кусочек прямоугольной формы.

http://floomby.ru/content/cJPKA44kkE/

Шаг третий. Крутим его до сигаретной формы. Поджигаем. Суем в рот. И вдыхаем знания :huh:

http://floomby.ru/content/BW2AFKg0n0/

Link to comment
Share on other sites

  • 0

ня, ня, ня и т.д.

долго врубался в час ночи в исходный код. ня.

если это то, что надо выбрать из одной таблицы данные по полю другой, то это, как вариант

SELECT table2.*

FROM table2

LEFT JOIN table1 ON (table2.field2 = table1.field)

WHERE table1.field IS NOT NULL;

кстати слегка модифицированный пример из манула MySQL

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

Link to comment
Share on other sites

  • 0

используй такой класс:

<?php
class DB{
public $m;
public $query_id;
public $rezult;
public function __construct()
{
if($this->m = @mysql_connect('localhost', 'root', '')){
if(@mysql_select_db('test')){
return true;
}else{
$this->error = 'Не могу выбрать базу!';
}
}else{
$this->error = 'Не могу подключится!';
}
}

public function __set($n, $t)
{
if($n == 'error'){
echo "<p style=\"color:red;\">$t</p>";
exit;
}elseif($n == 'query'){
if(!$this->query_id = mysql_query($t)){$this->error = "Не могу выполнить запрос!";}
}elseif($n == 'array_a'){
$this->query = $t;
while(($o = mysql_fetch_array($this->query_id))!=false){
$this->rezult[] = $o;
}
}elseif($n == 'line'){
$this->query = $t;
$this->rezult = mysql_fetch_array($this->query_id);
}
}
}

$obj = new DB();
$obj->array_a = "SELECT * FROM table_1";
print_r($obj->rezult);
?>

чтоб написать этот класс у меня ушло 15 мин.

Edited by -=PSU=-
Link to comment
Share on other sites

  • 0
У меня иногда идут цикл в цикле а в нем по несколько запросов, поэтому такой вариант не прокатит.

ты предлагаешь, что если у меня будет 10 запросов, то мне 10 переменных делать?

Я как и homm предлагаю включить мозг, а не ждать натс. Ты привел конкретный пример я выдал конкретный ответ.

Если у тебя 10 запросов и после каждого запроса есть готовый результат то его надо отдать клиенту. если это 10 запросов связывающих 10 таблиц базы данных то проще сделать один "трехэтажный" запрос, и не пренебрегать функционалом базы данных. это мое имхо: есть и плюсы и минусы трехэтажных запросов. но это не относиться к теме.

Так же если например 5 таблиц базы данных связывают информацию одного объекта (меню например) а другие 5 другого (информация о контенте) то это два разных объекта. соответственно два разных класса, наследники третьего: работа с базой данных (например). причем экземпляры этих первых двух классов (конечные объекты) не пересекаются в родителе (не имеют общих переменных - т.е названия переменных одни и теже. но физическое адресное пространство разное).

Вообще наследовать класс базы данных не есть хорошая логика - так как в 99% случаев требуется лишь один экземпляр этого класса для работы приложения, а не реализация этого класса во множестве других, т.е множество других экземпляров класса базы данных (10 потомков класса создат 10 соединений с БД, умножая на среднее количесво юзеров сайта, получаем нагрузку канала передачи данных; хотя приложение выполняется последовательно, но есть небольшой лимит времени в течение которого существует открытое соединение, ессно дело если ручками его не закрывать).

vvsh, если у тебя не получается вникнуть в ОПП на абстрактных процессах, используй материальные: приготовление кофе, например. Чашка, ложка, турка, кофе, сахарница и т.п - это объекты, с определенным интерфесом доступа к своим свойствам. Рецепт кофе: "Кофе по турецки" - это модель. Ты сам - это контроллер, который связывает объекты, их свойста и их методы с моделью для получения результата (представление): попить кофе по турецки.

Так что возьми листочек бумаги и коды подейшь пить кофе запиши всю последовательность действий над объектами и их свойствами, сгруппируй, проанализируй, обобщи в классах (шаблонах объектов) и получишь "приложение" кофепития :(

Link to comment
Share on other sites

  • 0

2 -=PSU=- не пропрет у него этот класс: public $rezult;. wsh постоянно будет перезаписывать эту переменную в процессе выполнения своего алгоритма, как и раньше было. там надо что-то типа return $result где $result внутренняя переменная функции, перед каждым запросом чистая. По хорошей логике класс БД должен получить запрос, получить тип ответа, выполнить запрос, отформатировать результат и отдать его, не запоминая. А вот "то что" запросило должно распорядиться с этим результатом как требует "этого чего-то" логика.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy