PHP / MySQL, изолирующий доступ к базе данных в классе - как обрабатывать наборы результатов из нескольких строк в ООП - PullRequest
1 голос
/ 27 августа 2009

PHP / MySQL, изолирующий доступ к базе данных в классе - как обрабатывать несколько строк.

Вот кодовый вопрос. Я выделил все функции доступа к БД в классе

<?php
class DB {
    var $conn;         
    function DBClass () {
                @$this-> conn = mysqli_connect (DB_SERVER, DB_USER, DB_PASS, DB_NAME);
    }
    function validateUser ($aUserid, $aPassword) {
                …  validation code – sql injection code etc..
                $sql = "Select userid, name, level From users where userid = '$aUserid' and password = '$aPassword'";
                $result = mysqli_query ( $this->conn, $sql );
                if (!$result || (mysqli_num_rows ($result) < 1)) {
                            return false;
                }
                $dbarray = mysqli_fetch_assoc ($result); // get a row
                return $dbarray;
    }

    function getProduct ($aProductid) {

                return $dbarray;
    }

    function getProductList () {  
                // <----------- this would be the problem function
    }
}

$DB = new DBClass();
?>

Моя процедура звонка:

<?php
        $dbarray = $DB->validateUser ($_POST['userid'], $_POST['password']); 
?>

Нет проблем, он работает нормально. Я столкнулся с проблемой с набором результатов более чем одной строки. Теперь я должен вернуться к объекту класса для каждой строки. Нет проблем, если я включу код MySQL в процедуру вызова, но я хотел бы сохранить его изолированным в своем классе и не уверен, как его кодировать.

Есть мысли? Есть примеры?

Ответы [ 3 ]

1 голос
/ 27 августа 2009

Если вы используете PHP 5.3.0 и mysqlnd, вы можете использовать новую функцию mysqli_fetch_all(). Это возвращает массив ассоциативных массивов.

Если вы используете более раннюю версию PHP, вы можете переключиться на использование PDO и использовать функцию PDOStatement::fetchAll().

Вы спрашиваете в комментарии, как насчет очень большого набора результатов. Это правда, что неограниченный набор результатов может привести к тому, что массив превысит ваш предел памяти PHP, что приведет к фатальной ошибке и остановит скрипт. Но действительно ли это проблема? Сколько продуктов у вас есть? Вы можете использовать LIMIT, чтобы убедиться, что запрос не является неограниченным.


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

class DB implements IteratorAggregate
{
  protected $_data = array();

  public function getProductList() {
    // fetch all results from SQL query, stuff them into $this->_data
    return $this->getIterator();
  }

  public function getIterator() {
    return new ArrayIterator($this->_data);
  }
}

Теперь вы можете использовать класс в цикле foreach:

$db = new DB();
foreach ($db->getProductList() as $product) {
  // do something with each product
}

Интерфейс IteratorAggregate означает, что вы даже можете сделать это:

$db = new DB();
$db->getProductList();
// ...other steps...
foreach ($db as $product) {
  // do something with each product
}

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

1 голос
/ 27 августа 2009

вы можете сохранить результат в массив и вернуть его:

function getProductList () {
   $sql = "SELECT ...";
   $result = mysqli_query ( $this->conn, $sql );

   $myProducts = array();

   while ($row = mysqli_fetch_assoc($result))
      $myProducts[] = $row; // or array_push($myProducts, $row)
   }

   return $myProducts
}

В результате у вас будет массив массивов, и каждый его элемент будет содержать одну строку результата.

0 голосов
/ 27 августа 2009

У вас есть SQL-инъекция прямо на вашей странице входа в систему.

Что произойдет, если кто-то введет это в качестве пароля: xxx 'ИЛИ' гггг <> 'х

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...