Avatar billede albert Juniormester
02. oktober 2009 - 20:08 Der er 37 kommentarer og
1 løsning

OOP login

Jeg har arbejdet med et login script i OOP. Jeg har desværre ikk helt tjek på OOP og den virker desværre ikke helt..

Men her har i selve min OOP kode fra klassefilen:

<?php

    class Login{
   
        public $userid;
        public $password;
       
        public function setUserid($userid){
            $this->userid = $userid;
        }
       
        public function setPassword($password){
            $this->password = $password;
        }
       
        public function getUserid(){
            return $this->userid;
        }

        public function getPassword(){
            return $this->password;
        }

        public function LogIn(){
       
            $uid = addslashes($_POST[$this->userid]);
            $pwd = md5(addslashes($_POST[$this->password]));
           
            $query = $mysqli->query("SELECT * FROM medlemmer where userid='".$uid."' and password='".$pwd."'");
            $result = mysqli_fetch_array($query);
                                           
            if(@$result){
                $_SESSION['adgang'] = true;
                $_SESSION['id'] = $result['id'];
                header("location:finans.php?page=frontpage");
                exit;
            }else{
                $_SESSION['adgang'] = false;
                echo "Forkert brugernavn og / eller kodeord";
                exit;
            };
        }
    }

?>

Og her har i koden fra min index.php:

<?php
if(isset($_POST['submit'])){
    $LogIn = new LogIn();
    $LogIn->setUserid($_POST['userid']);
    $LogIn->setPassword($_POST['password']);
};
?>

Er der nogle der kan se hvad det er jeg gør forkert?
Avatar billede albert Juniormester
02. oktober 2009 - 20:08 #1
Og ja, jeg har sat mysqli variablen
Avatar billede repox Seniormester
02. oktober 2009 - 20:29 #2
Til at starte med kunne du jo lade være med at undertrykke fejlmeddelelser.

Og det ville være rart at vide hvordan du konstaterer det ikke virker?
Avatar billede Slettet bruger
02. oktober 2009 - 20:33 #3
Jeg er hellet ingen haj til objektorienteret programmering, men det her set forkert ud for mig:

$uid = addslashes($_POST[$this->userid]);
$pwd = md5(addslashes($_POST[$this->password]));

Skulle det ikke hellere være:

$uid = addslashes($_POST[userid]);
$pwd = md5(addslashes($_POST[password]));

eller

$uid = addslashes($this->userid);
$pwd = md5(addslashes($this->password));
Avatar billede repox Seniormester
02. oktober 2009 - 20:45 #4
#3
Du erstatter fejl med fejl.
Index-angivelserne i de $_POST's er ganske givet ikke angivet som konstanter.

#0, #1
Udover de fejl som kimsey0 udpeger, lader det ikke til at $mysqli er instancieret.
Du siger godt den er, men din klasse viser ikke en instanciering af $mysqli i dit objekts scope.

Variabler - som ikke er defineret som globale - eksisterer kun i det scope de er oprettet i ($_POST, $_GET, $_SESSION og lign. er superglobaler og er en klasse for sig).
Avatar billede Slettet bruger
02. oktober 2009 - 20:55 #5
#4
Undskyld. Der skulle selvfølgelig have været gåseøjne rundt om "userid".

$uid = addslashes($_POST["userid"]);
$pwd = md5(addslashes($_POST["password"]));
Avatar billede arne_v Ekspert
03. oktober 2009 - 01:43 #6
Lidt blandede kommentarer:

1) mysqli har bedre metoder end addslashes til at beskytte mod SQL injection

2) det er ikke nødvendigt at addslashe noget der skal hashes

3) hvis der er frit valg af hashing funktion, så er MD5 ved at være lidt gammel

4) jeg mener at den er helt gal med kode strukturen, mit forslag:

en klasse til at repræsentere en bruger og dens data

en anden klasse med en metode til at checke om brugernavn/password er valid

noget helt tredie kode til at outputte respons til login request
Avatar billede albert Juniormester
03. oktober 2009 - 09:58 #7
Tak kimsey0, Jeg har vidst lavet en lille dum fejl der som du skriver...

Men fejlen er nu:

Notice: Undefined variable: mysqli in C:\wamp\www\finans\functions\albert\login.php on line 29

Fatal error: Call to a member function query() on a non-object in C:\wamp\www\finans\functions\albert\login.php on line 29

Arne_v:
Jeg er ikk god til OOP, og det må jeg indrømme. Men har du et forslag til hvordan strukturen så skal være på min kode?
Avatar billede Slettet bruger
03. oktober 2009 - 11:40 #8
Jeg vil endnu gerne gentage, at jeg ikke er en haj til OOP, og jeg kender heller ikke særligt meget til mysqli, men måske kunne du undgå fejlen ved at oprette MySQLi objektet i Login objekts construktor. Altså:

class Login{

  function __construct() {
      $mysqliInstance = new mysqli;
  }

...Blah, blah, blah...

$query = $mysqliInstance->query("SELECT * FROM medlemmer where userid='".$uid."' and password='".$pwd."'");

...Blah, blah, blah...

}
Avatar billede albert Juniormester
03. oktober 2009 - 11:59 #9
Den fejl har jeg rettet med en $GLOBALS['mysqli'];
Avatar billede Slettet bruger
03. oktober 2009 - 13:34 #10
Fedt.
Virker alt så, og kan vi lukke?
Avatar billede albert Juniormester
03. oktober 2009 - 13:37 #11
Alt virker ikke helt... For den header ikke over til den side som jeg vil have den skal... Den kommer ikke op med nogle fejl..
Avatar billede dkfire Nybegynder
03. oktober 2009 - 14:14 #12
Der er flere ting du kan gøre. I stedet for at kalde header, kan du lave et lille echo som kan fortælle dig hvor langt koden er nået.

Dernæst bør du vise hvordan din kode ser ud nu samt hvordan du bruger din klasse.

Du bør også se på om der kunne være en mysql fejl.
Det kan du gøre ved: 
$query = $mysqli->query("SELECT * FROM medlemmer where userid='".$uid."' and password='".$pwd."'") or die($mysqli->error);

Du bør også se på hvor mange rækker din sql giver dig:
printf("Select returned %d rows.\n", $query->num_rows);
Avatar billede albert Juniormester
03. oktober 2009 - 18:00 #13
Lige nu sidder jeg ikk ved min computer hvor jeg har se filer... men jeg skal nok prøve det på mandag:)
Avatar billede albert Juniormester
05. oktober 2009 - 10:47 #14
Jeg har prøvet alt hvad du har skrevet dkfire. Den siger at der er 0 rækker i posten. Men det ved jeg at der ikke er... Jeg tror at jeg er ved at blive skør på det her...

Men jeg forstår ikke helt hvad det er du mener med at jeg skal vise min kode. for det gør jeg jo oppe i toppen...
Avatar billede repox Seniormester
05. oktober 2009 - 10:58 #15
#14
Det dkfire vil er at se din kode i sin nuværende form. Du har jo foretaget rettelser siden dit første indlæg.
Forhåbentlig vil der også være en snert af indtrængen af de gode råd der er kommet fra både dkfire og arne_v, således du har fået en løsning som er til at arbejde med.
Avatar billede albert Juniormester
05. oktober 2009 - 11:01 #16
Okay her kommer den:)

<?php
    class Login{
   
        public $userid;
        public $password;
       
        public function setUserid($userid){
            $this->userid = $userid;
        }
       
        public function setPassword($password){
            $this->password = $password;
        }
       
        public function getUserid(){
            return $this->userid;
        }

        public function getPassword(){
            return $this->password;
        }

        public function LogIn(){
       
            $uid = addslashes($this->userid);
            $pwd = md5(addslashes($this->password));
           
            $query = $GLOBALS['mysql']->query("SELECT * FROM medlemmer where userid='".$uid."' and password='".$pwd."'")or die($mysqli->error);
            $result = mysqli_fetch_array($query);
                   
            printf("Select returned %d rows.\n", $query->num_rows);        
            echo "<br />";               
           
            if(@$result){
                /*$_SESSION['adgang'] = true;
                $_SESSION['id'] = $result['id'];
                header("location:finans.php?page=frontpage");
                exit;*/
                echo "rigtigt";
            }else{
                //$_SESSION['adgang'] = false;
                echo "Forkert brugernavn og / eller kodeord";
                //exit;
            };
        }
    }
?>


index.php:

<body>

<div id="DivWrapper">
    <div style="text-align:center; padding:10px;"><h1 class="FontFinansOverskrift">PCN FINANS</h1></div>
    <form action="index.php" method="post">
        <table cellpadding="4" cellspacing="4" border="0" style="margin:0 auto;">
            <tr>
                <td>
                    Brugerid:
                </td>
                <td>
                    <input type="text" name="userid" />
                </td>
            </tr>
            <tr>
                <td>
                    Password:
                </td>
                <td>
                    <input type="password" name="password" />
                </td>
            </tr>
            <tr>
                <td>
                 
                </td>
                <td>
                    <input type="submit" name="submit" value="Log ind" />
                </td>
            </tr>
        </table>
    </form>
<?php
if(isset($_POST['submit'])){
    $LogIn = new LogIn();
    $LogIn->setUserid($_POST['userid']);
    $LogIn->setPassword($_POST['password']);
};
?>

</div>

</body>
Avatar billede repox Seniormester
05. oktober 2009 - 12:36 #17
Det eneste du har gjort er at gøre din $mysqli variabel global, tilføjet en die() til denne og tilføjet en echo af antal fundne rækker i databasen?

Din klasse er stort set ubrugelig og har ikke nogen værdi, set i forhold til almindelig processuel kode.

Hvis det her er et forsøg på at blive bedre til at skrive objekt orienteret kode, ville det være bedre at få vurderet dit objekt - hvad der kan gøres smartere og hvad der kan gøres bedre - i forhold til hvad man ville ønske at opnå med OOP optimeret kode.
Avatar billede albert Juniormester
05. oktober 2009 - 12:51 #18
Jeg er altid parat til at lære mere... Jeg mangler bare nogle forslag. Jeg er lige startet med OOP og ja jeg er ikke særlig god til OOP. Men kan du vise mig nogle tricks, til hvordan det kan gøres smartere?

Jeg vil med glæde gerne lave et nyt spørgsmål, så du kan få nogle flere point...
Avatar billede dkfire Nybegynder
05. oktober 2009 - 13:04 #19
Se det hjalp jo meget.
Du bruger din klasse helt forkert.

<?php
if(isset($_POST['submit'])){
    $LogIn = new LogIn() ;  <-- Du opretter et objekt af klassen og samtidig prøver du at logge ind.
    $LogIn->setUserid($_POST['userid']); <-- Du sætter username
    $LogIn->setPassword($_POST['password']); <-- du sætter password
};
?>

Dvs du prøver at logge ind med tomme værdier for username og password. Derfor giver den 0 rækker tilbage, da du ikke har en rækker med tomme felter i din tabel i databasen.
Du bliver nød til at ændre din klasse, således at din klasse contructor ikke laver database tjekket, men kun initialisere din klasse's objekt.
Dernæst skal du lave en ny funktion i klassen som laver dit databasen tjek og logger ind. Den funktion kalder du så efter du har sat brugernavn og kodeord.
Avatar billede albert Juniormester
05. oktober 2009 - 13:08 #20
Jeg spørger igen meget dumt...
Hvordan laver jeg min klasse constructor til at initialisere min klasses objekt?

Jeg er ikk særlig god...:(
Avatar billede repox Seniormester
05. oktober 2009 - 13:15 #21
Hvis du vil lære mere, skal du også vise at du er villig til at høre efter.
arne_v og dkfire kom med nogle konstruktive indlæg, som du tilsyneladende har overset. Om det var i jagten på en løsning fremfor læren, skal jeg ikke kunne sige.

Du kan få et eksempel på et objekt du kan tilpasse som du beskriver det som dkfire og arne_v så venligt har forsøgt at forklare dig:
http://php.pastebin.com/m76e2b5d7

Koden er ikke testet, så eventuelle syntaks fejl må du lige berede dig på.
Avatar billede albert Juniormester
05. oktober 2009 - 13:29 #22
hvad gør denne linje?:

$row = $result->fetch_array(MYSQLI_ASSOC);
Avatar billede albert Juniormester
05. oktober 2009 - 13:37 #23
og for at være helt krævende...:S
$userid = $this->mysqli->real_escape_string($userid);
Avatar billede repox Seniormester
05. oktober 2009 - 13:41 #24
Du bruger selv mysqli_fetch_array() så det burde du da vide?
Ellers: http://dk2.php.net/manual/en/mysqli-result.fetch-array.php

mysqli_real_escape_string() er et mere sikkert alternativ end addslashes().
Avatar billede albert Juniormester
05. oktober 2009 - 13:46 #25
Jeg kan bare se at du skriver $this->mysqli-> før jeg lægger min post ind i en variabel
Avatar billede albert Juniormester
05. oktober 2009 - 13:47 #26
Og tak jeg har fået det til at virke:)
Avatar billede repox Seniormester
05. oktober 2009 - 13:48 #27
Du ved vel at $this->mysqli referer til dit mysqli objekt, som jeg instancierede i __construct()?
Avatar billede albert Juniormester
05. oktober 2009 - 13:51 #28
jo det gør jeg...
Avatar billede dkfire Nybegynder
05. oktober 2009 - 14:02 #29
Du bør nok læse lidt på oop, klasser og objekter. Men jeg skal forsøge.

Når din klasse hedder Login, så vil din funktion, metode, i klassen af samme navn være din contructor for denne klasse. ( I PHP5 hedder klassens contructor __constructor() )
Hvis du vil have at objectet af klassen Login skal udføre noget lige så snart det bliver initialiseret, ( ved "new Login()), skal den kode ligge i din contructor af klassen.
Men i din tilfælde skal din klasse jo ikke forsøge at logge ind før du har givet et brugernavn og password den skal tjekke i databasen.
Derfor skal din kode til login ikke ligge i constructoren af klassen men i en anden funktion, metode, i klassen.

Din klasse kunne jo se ud som følgende:

class Login{
 
        private $userid;
        private $password;
        public $mysqli;

        public function Login($mysqli){
            $this->mysqli = $mysqli;
        }

        public function setUserid($userid){
            $this->userid = $userid;
        }
     
        public function setPassword($password){
            $this->password = $password;
        }
     
        public function getUserid(){
            return $this->userid;
        }

        public function getPassword(){
            return $this->password;
        }

        public function doLogIn(){
     
            $uid = addslashes($this->userid);
            $pwd = md5($this->password);
         
            $query = $mysqli->query("SELECT * FROM medlemmer where userid='".$uid."' and password='".$pwd."'")or die($mysqli->error);
            $result = mysqli_fetch_array($query);
                 
            printf("Select returned %d rows.\n", $query->num_rows);       
            echo "<br />";             
         
            if(@$result){
                /*$_SESSION['adgang'] = true;
                $_SESSION['id'] = $result['id'];
                header("location:finans.php?page=frontpage");
                exit;*/
                echo "rigtigt";
            }else{
                //$_SESSION['adgang'] = false;
                echo "Forkert brugernavn og / eller kodeord";
                //exit;
            };
        }
    }


if(isset($_POST['submit'])){
    $LogIn = new Login($_GLOBAL['mysqli']);
    $LogIn->setUserid($_POST['userid']);
    $LogIn->setPassword($_POST['password']);
    $LogIn->doLogIn();
};
Avatar billede albert Juniormester
05. oktober 2009 - 14:46 #30
Nu må i endelig ikke forvirre mig... Jeg troede lige at det jeg først lavede var noget rod... Og så kommer der sådan et forslag som ligner meget på den jeg selv lavede. Det er måske ikk helt galt?
Avatar billede repox Seniormester
05. oktober 2009 - 14:52 #31
dkfires sidste forslag forklarer dig hvordan du kunne få den eksisterende kode til at virke efter hensigten da du havde nogle ret elementære fejl. Dog mener jeg stadig at den klasse har en ringe værdi.

Det forslag jeg kom med er jeg - selvfølgelig - overbevist om er en bedre og mere fleksibel løsning - også set ud fra de kommentarer som både dkfire og arne_v er kommet med.

OOP er meget mere end hvad jeg kan skitsere i så simpelt et eksempel, men nu har du noget at gå ud fra.
Avatar billede albert Juniormester
05. oktober 2009 - 14:56 #32
Tak:)
I må endelig lægge et svar:)
Avatar billede albert Juniormester
05. oktober 2009 - 15:09 #33
Lige et sidste spørgsmål?
Kender sådan nogle kloge hoveder som jer, nogle godt steder hvor man evt. kan tage kurser i OOP? Jeg ønsker at lære mere men kan desværre ikke læse mig frem til ret meget.
Jeg prøver at læse dokumentationen i php.net's hjemmeside og fatter det halve af hvad der står der inde...
Avatar billede repox Seniormester
05. oktober 2009 - 15:39 #34
Du opnår ikke meget andet end at lære brugen af OOP og de muligheder med OOP PHP giver dig, ved at læse manualen.

En god resource ville være at gå på google og søge på php design patterns og læse lidt op på det.

Eventuelt kunne du sætte dig et projekt for dagen; det kunne være du ville lave en klasse som kunne en specifik ting du tit har brug for. Lav din egen udgave af klassen, spørg herinde om der er nogen der har kritik/forslag til din kode.
Avatar billede albert Juniormester
05. oktober 2009 - 15:40 #35
Okay det skal jeg gøre:)
Tak...
Avatar billede dkfire Nybegynder
05. oktober 2009 - 19:48 #36
Jeg må nok indrømme at det er meget lang tid siden jeg har haft et kursus i oop, og det var ikke et man sådan bare lige tog, og desværre heller ikke i php men c++.

Men jeg har nu haft glæde af at læse:
http://www.amazon.co.uk/PHP-MySQL-Development-Developers-Library/dp/0672329166/ref=sr_1_1?ie=UTF8&s=books&qid=1254763754&sr=8-1
Dog var det tredje version.

Ellers findes der faktisk mange gode bøger på biblioteket som omhandler php og oop.

Design patterns vil også være en god ide at læse op på, men det synes jeg du først skal tage når du er blevet lidt mere bekendt med php og oop.

Der må også findes nogle tutorials på nettet, prøv at søg. Evt kunne du jo hører her på eksperten om dem du finder er noget værd.
Avatar billede albert Juniormester
27. november 2011 - 22:00 #37
lukker
Avatar billede arne_v Ekspert
27. november 2011 - 22:08 #38
Hvorfor tog du selv point her??
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