J'ai une classe MySQL singleton écrite en PHP. Son code est ci-dessous:Conflits de classes MySQL singleton avec fonction récursive (PHP)
class Database {
private $_result = NULL;
private $_link = NULL;
private $_config = array();
private static $_instance = NULL;
// Return singleton instance of MySQL class
public static function getInstance(array $config = array()) {
if (self::$_instance === NULL) {
self::$_instance = new self($config);
}
return self::$_instance;
}
// Private constructor
private function __construct(array $config) {
if (count($config) < 4) {
throw new Exception('Invalid number of connection parameters');
}
$this->_config = $config;
}
// Prevent cloning class instance
private function __clone() {}
// Connect to MySQL
private function connect() {
// Connect only once
static $connected = FALSE;
if ($connected === FALSE) {
list($host, $user, $password, $database) = $this->_config;
if ((!$this->_link = mysqli_connect($host, $user, $password, $database))) {
throw new Exception('Error connecting to MySQL : ' . mysqli_connect_error());
}
$connected = TRUE;
unset($host, $user, $password, $database);
}
}
// Perform query
public function query($query) {
if (is_string($query) and !empty($query)) {
$this->connect();
if ((!$this->_result = mysqli_query($this->_link, $query))) {
throw new Exception('Error performing query ' . $query . ' Message : ' . mysqli_error($this->_link));
}
}
}
// Fetch row from result set
public function fetch() {
if ((!$row = mysqli_fetch_object($this->_result))) {
mysqli_free_result($this->_result);
return FALSE;
}
return $row;
}
// Get insertion ID
public function getInsertID() {
if ($this->_link !== NUlL) {
return mysqli_insert_id($this->_link);
}
return NULL;
}
// Count rows in result set
public function countRows() {
if ($this->_result !== NULL) {
return mysqli_num_rows($this->_result);
}
return 0;
}
// Close the database connection
function __destruct() {
is_resource($this->_link) AND mysqli_close($this->_link);
}
}
J'ai aussi cette fonction récursive qui doit retourne un arbre de catégorie complète (la table SQL et son contenu peut être trouvé here):
function getCategories($parent = 0) {
$html = '<ul>';
$query = "SELECT * FROM `categories` WHERE `category_parent` = '$parent'";
$database->query($query);
while($row = $database->fetch()) {
$current_id = $row->category_id;
$html .= '<li>' . $row->category_name;
$has_sub = 0;
$query = "SELECT `category_parent` FROM `categories` WHERE `category_parent` = '$current_id'";
$database->query($query);
$has_sub = $database->countRows();
if ($has_sub > 0) {
$html .= getCategories($current_id);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
Maintenant, le problème est que la fonction retourne seulement 3 catégories, pas l'arbre complet. J'ai réécrit la fonction en utilisant des fonctions MySQL simples (mysql_query(), mysql_fetch_object() etc.) et cela retourne le bon résultat.
Donc, ma conclusion en ce qu'il y a quelque chose de mal avec cette classe. Notez que j'ai utilisé cette classe dans la plupart de mes projets, mais je n'ai jamais eu ce problème.
Une idée quoi?
Merci.
EDIT: Essayer de faire retourner un tableau associatif
function getCategories($parent = 0) {
global $database;
$categories = array();
$query = "SELECT * FROM `categories` WHERE `category_parent` = '$parent'";
$database->query($query);
while($row = $database->fetch()) {
$categories[] = array('id' => $row->category_id, 'name' => $row->category_name);
}
for ($i = 0; $i < count($categories); $i++) {
$categories[$i]['id']['children'] = getCategories($categories[$i]['id']);
}
return $categories;
}
Le code ci-dessus renvoie le tableau suivant, mais pas tout à fait correct:
Array
(
[0] => Array
(
[id] => 1
[name] => Categoria 1
[children] => Array
(
[0] => Array
(
[id] => 4
[name] => Categoria 1.1
[children] => Array
(
[0] => Array
(
[id] => 7
[name] => Categoria 1.1.2
[children] => Array
(
)
)
)
)
[1] => Array
(
[id] => 5
[name] => Categoria 1.2
[children] => Array
(
)
)
[2] => Array
(
[id] => 6
[name] => Categoria 1.3
[children] => Array
(
)
)
)
)
[1] => Array
(
[id] => 2
[name] => Categoria 2
[children] => Array
(
)
)
[2] => Array
(
[id] => 3
[name] => Categoria 3
[children] => Array
(
)
)
)
Est-ce le code complet de 'getCategories'? Ne devrait-il pas y avoir un appel '$ database = Database :: getInstance()'? –
Vous faites beaucoup de réinvention de la roue ici. Avez-vous envisagé d'utiliser [mysqli en mode objet] (http://us2.php.net/manual/fr/class.mysqli.php) au lieu du mode procédural et d'étendre simplement les classes pour obtenir toutes les fonctions de commodité que vous désirez? Ou en utilisant [PDO] (http://us2.php.net/manual/fr/book.pdo.php) et en faisant la même chose? – Charles
@George Marian: oui, cet appel est là dans le script, mais je ne l'ai pas posté ici. – Psyche