Avatar billede Slettet bruger
26. september 2007 - 11:52 Der er 17 kommentarer

PHP class problemer

Hej eksperter jeg har 4 filer, og tror det er min extends den er gal med!:
index.php
connection.cls.php
query.cls.php
user.cls.php

index.php, includer_once user.cls.php
connectiion.cls.php, laver database forbindelsen
query.cls.php, laver selve forspørgelserne til databasen, og extender fra Connection
user.cls.php, mit ikke færdige login system, som extender fra Query


Fejlen jeg modtager: Fatal error: Call to undefined method User::noConnection() in cls/query.cls.php on line 8


index.php --------------------------------------------------------
<?PHP
error_reporting(~0);
    include_once("cls/user.cls.php");
   
    $userObj = new User();
   
    if($_SERVER['REMOTE_ADDR'] == "83.73.249.171") {
        if(isset($_POST['sub_login'])) {
            $userObj->userLogin($_POST['user'], $_POST['pass']);
        } else {
?>
<form action="" method="post">
    <table width="100%" cellpadding="0" cellspacing="0">
        <tr>
            <td align="left" valign="top">&nbsp;</td>
            <td colspan="2" align="left" valign="top" style="height: 25px;">Cookies skal være sat til for at kunne logge ind.</td>
        </tr>
        <tr>
            <td align="right" valign="top">Brugernavn:</td>
            <td align="right" valign="top">&nbsp;</td>
            <td align="left" valign="top"><input type="text" name="user" value="Brugernavn" onFocus="if(this.value=='Brugernavn') { this.value = ''; }" onblur="if(this.value=='') { this.value = 'Brugernavn'; }" /></td>
        </tr>
        <tr>
            <td align="right" valign="top">Kodeord:</td>
            <td align="right" valign="top">&nbsp;</td>
            <td align="left" valign="top"><input type="password" name="pass" value="Kodeord" onFocus="if(this.value=='Kodeord') { this.value = ''; }" onblur="if(this.value=='') { this.value = 'Kodeord'; }" /></td>
        </tr>
        <tr>
            <td colspan="2" align="right" valign="top">&nbsp;</td>
            <td align="left" valign="top"><input type="submit" name="sub_login" value="Login" /></td>
        </tr>
    </table>
</form>
<?PHP
        }
    }
?>


connection.cls.php -----------------------------------------------
<?PHP
    class Connetion {
        protected $host = "********";
        protected $user = "********";
        protected $password = "********";
        protected $database = "********";
       
        protected $dbhandler;
        protected $db2handler;
       
        protected $show_errors = true;
       
        function __construct() {
            $msg = "";
            $mysql_connect = mysql_connect($this->host, $this->user, $this->password);
           
            if(!$mysql_connect) {
                $msg .= "<span class=\"errorMsg\">Cannot connect to the database. ".mysql_error()."</span>";
            } else {
                $mysql_select_db = mysql_select_db($this->database, $mysql_connect);
            }
           
            if(!$mysql_select_db) {
                $msg .= "<br /><span class=\"errorMsg\">Cannot selected the database. ".mysql_error()."</span>";
            }
            if(!$mysql_connect || !$mysql_select_db) {
                $this->noConnection($msg);
            }
                $this->dbhandler = $mysql_connect;
                $this->db2handler = $mysql_select_db;
            return;
        } // ends the function __construct
       
        public function noConnection($error) {
            /*if($this->show_errors)
                $error = "<br />\n<b>".$error."</b>";
            else
                $error = "";
                */
            exit("<span style=\"font-family: Verdana; font-size: 10px; color: #FF0000;\">Server opgraderes, dette kan tage op til 15 minutter!".stripslashes($error)."</span>");           
        } // end the function noConnection
       
        function __destruct() {
            @mysql_close($this->dbhandler);
        } // ends the function __destruct
       
    } // ens the class connection
?>

query.cls.php ----------------------------------------------------
<?PHP
include_once("connection.cls.php");
    class Query extends Connetion {
   
        public function returnSQL($sql) {
            if(!(strstr(strtoupper($sql), "INSERT") || strstr(strtoupper($sql), "DELETE") || strstr(strtoupper($sql), "UPDATE"))) {
                // ONLY SELECT STATESMENT IS ILLEGAL!
                $query = @mysql_query($sql, $this->dbhandler) or Die($this->noConnection(mysql_error()));;
                //if(!$query)
                //$this->noConnection("There is an error with this sql string. String is: ".$sql."<br />\n".mysql_error());
                $lines = array();
               
                while ($row = mysql_fetch_assoc($query)) {
                    $lines[] = $row;
                }
                return $lines;
            } else {
                $this->noConnection("Illegal sql commando : NO ".substr($sql, 0, 6)."!<br />\n".$sql);
            }           
        } // end the function returnSQL
       
       
       
        public function execSQL($sql) {
            if(!strstr(strtolower($sql), "SELECT")) {
                $query = @mysql_query($sql, $this->dbhandler) OR $this->noConnection("There is an error with this sql string. String is: ".$sql."<br />\n".mysql_error());
                if($query)
                    return true;
                else
                    return false;
            } else {
                $this->noConnection("Illegal sql commando<br />\n".$sql);
            }
        }
    } // end the class Query
?>
user.cls.php -----------------------------------------------------
<?PHP
include_once("query.cls.php");
    class User extends Query {
        protected $user;
        protected $pass;
       
        public function userLogin($user, $pass) {
            if(strlen($user) > 0 && strlen($pass) > 0) {
                $user = trim($user);
                $pass = md5($pass);
                $this->LogMeIn($user, $pass);
            } else {
                return false;
            }
        }
       
        public function LogMeIn($user, $pass) {
            $sql = "SELECT COUNT(*) as cnt FROM sn_user WHERE email = '".$user."' AND usr_pass = '".$pass."';";
            $query = parent::returnSQL($sql);
           
            if($query[0]['cnt'] == 1) {
                //setcookie()
                return "Velkommen";
            } else {
                return "fejl";
            }
        }
    } // end class User
?>
Avatar billede rax Praktikant
26. september 2007 - 12:24 #1
På den pågældende linie, linie 8 i query.cls.php, har du afsluttet med 2 x ; istedet for et. Prøv at rette det til et, og se om det ikke løser problemet. Hvorfor den siger, at du laver en statisk reference til en metode som ikke eksisterer er ikke lige til at forstå, men mit bud er, at det vil løse problemet, hvis du fjerner det ekstra semicolon.
Avatar billede Slettet bruger
27. september 2007 - 00:08 #2
Så er den rettet... men virker ikke...
Er det fordi jeg bruger exnteds 2 gange...?

index henter user filen ind, og den extender query filen, som extender connection filen... er det fordi de der include ikke bliver lavet i de på gældende filer?
Avatar billede Slettet bruger
27. september 2007 - 11:14 #3
Andre?
Avatar billede Slettet bruger
28. september 2007 - 13:58 #4
Hmm... da irriterene at den fejl kan gøre så meget!
Avatar billede Slettet bruger
29. september 2007 - 22:10 #5
rax flere bud?
Avatar billede nielle Nybegynder
29. september 2007 - 22:37 #6
1) Et ekstra ';' på sådan en plads vil aldrig give anledning til en fejl - det er simpelthen bare en ekstra (tom) linje kode.

2) Jeg forstår ikke lige hvorfor din fejl siger "User::..." eftersom at User-klassen slet ikke er blevet introduceret i query.cls.php. Har du nogen ide?

3) Set fra et OOP-perspektiv børe din User ikke extende Query - en brugere er jo basalt set ikke en database forbindelse. I stedet bør din User-klasse have et (private) Query objekt som det bruger til at slå op i databasen (forholdet mellem User og Query bør ændres fra is-a til has-a som man siger i OOP jargon).

4) På samme måde gælder der faktisk også at Query ikke bør extende Connection. I stedet bør Query bruge en Connection-klasse til at udføre sin forespørgsel.
Avatar billede Slettet bruger
30. september 2007 - 01:46 #7
I praksis hvordan gøres dette så?
Avatar billede nielle Nybegynder
30. september 2007 - 07:54 #8
F.eks. sådan:

user.cls.php -----------------------------------------------------
<?PHP
include_once("query.cls.php");

class User {
    protected $user;
    protected $pass;
       
    public function userLogin($user, $pass) {
        if (strlen($user) > 0 && strlen($pass) > 0) {
            $user = trim($user);
            $pass = md5($pass);
            $this -> LogMeIn($user, $pass);
        } else {
            return false;
        }
    }
       
    public function LogMeIn($user, $pass) {       
        $sql = "SELECT COUNT(*) as cnt FROM sn_user WHERE email = '$user' AND usr_pass = '$pass'";

        $logInQuery = new Query();
        $logInQueryResult = $logInQuery->returnSQL($sql);
           
        if ($logInQueryResult[0]['cnt'] == 1) {
            //setcookie()
            return "Velkommen";
        } else {
            return "fejl";
        }
    }
} // end class User
?>

Jeg har flyttet Query'en helt ind i LogMeIn() for det er jo kun der den skal bruges.
Avatar billede Slettet bruger
30. september 2007 - 11:03 #9
På den måde....
Hvad så med connection?
Avatar billede nielle Nybegynder
30. september 2007 - 19:17 #10
Det var nu ikke Connection, men derimod Query der burde ændres:

query.cls.php ----------------------------------------------------
<?PHP
include_once("connection.cls.php");

class Query {
    private $conn;

    function __construct() {
        $conn = new Connection()
    }

    public function returnSQL($sql) {
        if (!(strstr(strtoupper($sql), "INSERT") || strstr(strtoupper($sql), "DELETE") || strstr(strtoupper($sql), "UPDATE"))) {
            // ONLY SELECT STATESMENT IS ILLEGAL!
            $query = @mysql_query($sql, $conn->dbhandler) or die($conn->noConnection(mysql_error()));;
            // if(!$query)
            // $this->noConnection("There is an error with this sql string. String is: ".$sql."<br />\n".mysql_error());
            $lines = array();
               
            while ($row = mysql_fetch_assoc($query)) {
                $lines[] = $row;
            }

            return $lines;
        } else {
            $this->noConnection("Illegal sql commando : NO ".substr($sql, 0, 6)."!<br />\n".$sql);
        }
    } // end the function returnSQL


    // Øvelse: tilret selv execSQL() ..............

} // end the class Query
?>

$dbhandler i Connection skal selvfølgelig ændres fre protected til public.
Avatar billede Slettet bruger
01. oktober 2007 - 08:44 #11
Er det ikke lidt farligt sådan en data som $dbhandler, er public og kan tilgås fra alle?
Avatar billede nielle Nybegynder
01. oktober 2007 - 08:52 #12
Er det det?

I C# har man en access-modifier som kaldes "internal" - aller helst ville jeg have brugt den, men jeg mener ikke at den ekslistere i PHP.

Det vigtigste når du laver klasser er dog at de bør designes logisk. Hvis en klasse skal arve fra en anden, så bør det være fordi at den nedarvende klasse er en specialisering af super-klassen. En query er ikke en specialisering af en database-forbindelse...
Avatar billede Slettet bruger
01. oktober 2007 - 09:03 #13
Fisk... kan du så forklarer mig hvordan det gøres på den bedste måde?
Og ville det være smart at ha, alle sine kald i en samlet fil bare som databasekaldet, uden data fra databasen, hvis man nu skifter database, så kan man bare lige rette alle sammen i et dokument.
Avatar billede nielle Nybegynder
01. oktober 2007 - 18:12 #14
Øh, jeg troede ellers at jeg havde forklaret hvordan det skulle gøre i 30/09-2007 19:17:19?

Den med databasen, som udskiftes til en anden, er simpel nok: der skal bare rettes i connection.cls.php og så burde det slå igennem over at. :^)
Avatar billede nielle Nybegynder
07. oktober 2007 - 11:17 #15
Er du kommet videre med denne her?
Avatar billede Slettet bruger
08. oktober 2007 - 08:03 #16
Nej desværre ikke endnu.
Kigger på det, om et par timer.

Så skal jeg nok huske points til dig.
Avatar billede nielle Nybegynder
08. oktober 2007 - 18:25 #17
Ingen points før at vi har fået løst dit problem :^)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester