2010-08-19 7 views
3

Je pourrais manquer quelque chose ici, je ne suis pas sûr. Une recherche Google n'a pas vraiment aidé non plus.Comment créer une instance d'une classe dans une autre classe

Ce que je veux faire est d'appeler la classe databaseServer et d'utiliser ses méthodes dans ma classe userControl. Voici mon fichier lib_class.php:

<?php 

include('definitions.php'); 

class databaseServer { 

    var $con; 
    var $db; 
    var $close; 
    var $qry; 
    var $sql; 

    function connect($host,$user,$pw,$db) { 
     $this->con = mysql_connect($host,$user,$pw); 
     if (!$this->con) { 
      die('Could not connect: ' . mysql_error()); 
      } 
     else { 
      echo "Database Connected"; 
      } 
     $this->selectDb($db); 
     } 

    function selectDb($database) { 
     $this->db = mysql_select_db($database,$this->con); 
     if (!$this->db) { 
      echo "Could not Select database"; 
      } 
     else { 
      echo "Database Selected"; 
      } 
     } 

    function disconnect() { 
     $this->close = mysql_close($this->con); 
     if ($this->close) { 
      echo "Disconnected"; 
      } 
     } 

    function query($test) { 
     if (!mysql_query($test)) { 
      die("Error: " . mysql_error()); 
      } 
     } 

} // databaseServer 

class cookie { 

    var $expireTime; 

    function set($name,$value,$expiry) { 
     $this->expireTime = time()+60*60*24*$expiry; 
     setcookie($name,$value,$expireTime); 
     } 

    function delete($name) { 
     setcookie($name,"",time()-3600); 
     } 

    function check($name) { 
     if (isset($_COOKIE["$name"])) 
      echo "Cookie Set"; 
     else 
      echo "Cookie failed"; 
     } 

} //cookie 

class userControl { 

    public function __construct(databaseServer $server) { 
     $this->server = new databaseServer(); 
    } 

    function createUser($uname,$pword) { 

     $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME); 
     $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'"); 
     if ($this->result->num_rows() === 0) { 

      if ($this->server->query("INSERT INTO user_list (uname, pword) 
      VALUES ('" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") { 
       echo "User Added Successfully!"; 
      } 
      else { 
       echo "Error Adding User!"; 
      } 
     } 

     else { 
      echo "User Already Exists!"; 
     } 

    } // createUser 

} // userControl 

?> 

Cependant, cela ne fonctionne pas et je ne vois pas pourquoi. Mes classes databaseServer et cookie fonctionnent correctement lorsque j'omets la classe userControl du fichier, donc je sais que l'erreur doit être dans cette classe quelque part. La POO est quelque chose que j'essaie d'apprendre et je continue à trébucher.

Les échos de la classe databaseServer sont là uniquement pour que je puisse les tester. Je les cours dans la mise en œuvre d'un fichier index.php comme suit:

<?php 

include('definitions.php'); 
include('class_lib.php'); 

$bmazed = new databaseServer(); 

$bmazed->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME); 

$sql = "INSERT INTO blah 
VALUES ('testing 92')"; 

$bmazed->query($sql); 

$bmazed->disconnect(); 

// $control = new userControl(); 

// $uname = "Test1"; 
// $pword = "test1"; 

// $control->createUser($uname,$pword); 

echo "<br />"; 
echo "<br />"; 

?> 

Lines ont été commentés à des fins de test, donc je n'ai pas de garder le code récrire. Je n'ai vraiment aucune idée d'où vient le problème, j'ai vérifié la syntaxe et tout semble bien.

+0

J'ai essayé toutes les réponses suggérées, mais aucune d'entre elles ne semble fonctionner. J'ai édité la question originale pour montrer plus de mon code. Comme mentionné, le code est purement à des fins de test a donc quelques choses étranges là-bas comme des échos apparemment aléatoires. –

+0

@Saladin exécute 'php -l lib_class.php' et vous verrez qu'il se plaint de l'inattendu' {'et' else' dans le bloc 'if' où vous faites le' INSERT'. C'est parce qu'il vous manque une fermeture ')' sur ce bloc 'if'. Lorsque vous développez du code, assurez-vous que les options 'error_reporting' et' display_errors' sont activées. – Gordon

Répondre

2

Initialiser $server dans le constructeur:

class userControl { 

private $server; 

function __construct() { 
    $this->server = new databaseServer(); 
} 

function createUser($uname,$pword) { 
    $this->server->connect(DB_HOST,DB_USER,DB_PASS,DB_NAME); 
    $result = $this->server->query("SELECT * FROM user_list WHERE uname='" . $this->server->real_escape_string($uname) . "'"); 
    if ($this->result->num_rows() === 0) { 

    if ($this->server->query("INSERT INTO user_list (uname, pword) VALUES ('" . $this->server->real_escape_string($uname) . "','" . $this->server->real_escape_string($pword) . "')") { 
    echo "User added Succesfully"; 
    } 
    else { 
    echo "Error Adding User"; 
    } 

    else { 
    echo "User already exists"; 
    } 
} 

} 
+0

sauf dans la méthode createUser vous devriez référencer $ this-> server au lieu de $ server –

+0

@Mark Merci, corrigé! –

+1

'$ server' a besoin d'un mot-clé. Soit 'var' ou un modificateur de visibilité. – Gordon

6

Vous ne pouvez pas affecter de propriétés de classe ou d'instance qui dépendent des informations d'exécution lorsque vous déclarez les classes. Voir le chapter on Class Properties in the PHP Manual.

Modifier la classe à lire:

class userControl 
{ 
    protected $_server; 

    public function __construct() 
    { 
     $this->_server = new databaseServer(); 
    } 
} 

De plus, pour accéder à des membres de classe/instance, vous devez utiliser le mot-clé $this, par exemple

$this->_server->connect(); 

Sur un Sidenote, tandis que composition est très bien, aggregation est mieux. Il aide votre code à rester maintenable et à être faiblement couplé, ce qui signifie qu'il sera beaucoup plus facile de remplacer des composants, par exemple lors de l'écriture UnitTests. Donc, pensez à changer le constructeur pour utiliser Dependency Injection.

+4

Ou même mieux serait d'utiliser l'injection de dépendance pour mettre le serveur de base de données dans la classe 'funciton publique __construct (serveur $ DatabaseServer) {$ this -> _ server = $ server; } ' – ircmaxell

+0

Je ne suis pas d'accord avec votre utilisation des caractères de soulignement comme préfixes variables, étant donné que votre exemple est clairement le code PHP5. –

+0

@Alan J'utilise [la norme de codage de ZF] (http://stackoverflow.com/questions/1798916/why-does-the-zend-framework-prepend-an-underscore-here/1799034#1799034) mais n'hésitez pas à être en désaccord avec cette convention. Sur un sidenote, [les conventions de codage de PEAR nécessitent le trait de soulignement pour les propriétés privées, mais plus pour les propriétés protégées lors de l'utilisation de PHP5.] (Http://pear.php.net/manual/fr/standards.naming.php) – Gordon

1

D'une part, le serveur $ ne seront pas accessibles à l'intérieur createUser() parce qu'il est dans un cadre différent. La portée de PHP fonctionne un peu différemment de ce que l'on pourrait attendre d'un langage de style C. Essayez de transmettre le serveur $ à createUser() ou d'initialiser le serveur dans createUser(), auquel cas vous devriez probablement avoir une fonction getServer() pour ne pas l'initialiser inutilement.

La troisième option est de loin la pire, qui fait "global $ server" en haut, à l'intérieur de la fonction. Mais c'est une très mauvaise pratique. Tu étais prévenu.

Enfin et probablement, vous devriez probablement rechercher COUNT (*) que * dans la requête SQL, car sinon vous sélectionnez tous les utilisateurs. :)

Si vous souhaitez obtenir un complément d'informations sur la portée de PHP, voir ici (fortement recommandé): http://php.net/manual/en/language.variables.scope.php

Hope it helps!

0

La substance syntaxique était certainement un problème. Mais encore plus fondamentalement faux avec mon code était le fait que la méthode databaseServer-> requête ne renvoie pas une valeur. Le faire retourner une valeur fixe le problème.

Je pense, parfois, qu'il n'est pas possible de voir le bois pour les arbres. :)

Questions connexes