PHP: Bir sınıfta bir PDO veritabanı bağlantısı kullanarak doğru yolu

2 Cevap php

Sınıflara tüm kodumu düzenlemek için çalışıyorum, ve ben veritabanı sorgularını bir sınıf içinde çalışmak için alınamıyor. Ben sınıf sargı olmadan, test ve iyi çalıştı. Sınıf içinde = zar yok. What about my classes is messing this up?

EDIT: sorun veritabanını sorgulamak ve bir sonuca dönmek olmayacak olmasıdır. Herhangi bir sonuç.

class ac
  {
  public function dbConnect() 
    {
    global $dbcon;

    $dbInfo['server'] = "localhost";
    $dbInfo['database'] = "sn";
    $dbInfo['username'] = "sn";
    $dbInfo['password'] = "password"; 

    $con = "mysql:host=" . $dbInfo['server'] . "; dbname=" . $dbInfo['database'];
    $dbcon = new PDO($con, $dbInfo['username'], $dbInfo['password']);
    $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $error = $dbcon->errorInfo();

    if($error[0] != "") 
      {
      print "<p>DATABASE CONNECTION ERROR:</p>";
      print_r($error);
      }
    }


  public function authentication()
    {
    global $dbcon;

    $plain_username = $_POST['username'];
    $md5_password = md5($_POST['password']);

    $ac = new ac();
    if (is_int($ac->check_credentials($plain_username, $md5_password)))
      {
      ?>
      <p>Welcome!</p> <!--go to account manager here-->
      <?php
      }
    else
      {
      ?>
      <p>Not a valid username and/or password. Please try again.</p>
      <?php
      unset($_POST['username']);
      unset($_POST['password']);
      $ui = new ui();
      $ui->start();
      }
    }



  private function check_credentials($plain_username, $md5_password)
    {
    global $dbcon;

    $userid = $dbcon->prepare('SELECT id FROM users WHERE username = :username AND password = :password LIMIT 1');
    $userid->bindParam(':username', $plain_username);
    $userid->bindParam(':password', $md5_password);
    $userid->execute();

    print_r($dbcon->errorInfo());

    $id = $userid->fetch();
    Return $id;
    }
  }

Herhangi bir yardım Ve eğer, burada aradığını sınıfı bulunuyor:

require_once("ac/acclass.php");
$ac = new ac();
$ac->dbconnect();
class ui
  {
  public function start()
    {
    if ((!isset($_POST['username'])) && (!isset($_POST['password'])))
      {
      $ui = new ui();
      $ui->loginform();
      }
    else
      {
      $ac = new ac();
      $ac->authentication();
      }
    }

  private function loginform()
    {
    ?>
    <form id="userlogin" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
     User:<input type="text" name="username"/><br/>
     Password:<input type="password" name="password"/><br/>
     <input type="submit" value="submit"/>
    </form>
    <?php
    }
  }

2 Cevap

Için varsayılan PDOStatement::fetch sütun adı ve sayısına göre endeksli alanlarda bir dizi olarak bir satır döndürmek için (mod PDO::FETCH_BOTH). Bu ac::check_credentials bir dizi döndürür, ama bir tamsayı için ac::authentication denetler demektir. Ayrıca, alan değerleri dizeleri, bu yüzden açıkça bir tamsayı sonuç alanını dönüştürmek sürece is_int başarısız olur. PDOStatement::fetchColumn() and is_numeric deneyin.

    public function authentication() {
        ...
        if (is_numeric($this->check_credentials($plain_username, $md5_password))) {
        ...
    }

    private function check_credentials($plain_username, $md5_password) {
        return $userid->fetchColumn();
    }

Bir alternatif olarak is_numeric, kimlik denetiminin sonucu False ile aynı olmadığını kontrol edin.

    public function authentication() {
        ...
        if (False !== $this->check_credentials($plain_username, $md5_password)) {
        ...
    }

Some Stylistic Points

Yaggo işaret ettiği gibi, ui::start ve ac::dbConnect statik yöntemler olmalıdır. ac::authentication Yeni bir ac oluşturmanız gerekmez; Bu statik bir yöntem değil, çünkü o $this özel değişken (yukarıda yapıldığı gibi) aracılığı ile cari nesnesine erişebilirsiniz. $dbcon ac, statik bir özellik yapılmalıdır böylece yapmak değil pollute the global namespace. Sınıf adları UpperCamelCase kullanmak gerekir ve daha açıklayıcı olmalıdır.

Sınıflar tek bir iyi tanımlanmış bir amacı var ve bu sokak olmamalıdır. ac birçok amacı vardır: kimlik doğrulama ve görüntüleme sonuçlarını işlemek, DB bağlantısını yönetmek. Başka her şeyden veritabanı gizleme, bir Data Access Layer için sınıfları bir dizi tasarımı düşünün. Ayrıca ekrandan alanı mantığı (kimlik doğrulama ve c) ayıran düşünün. Bu Model View Controller mimarisi olarak bilinen modelin bir parçasıdır. Bu seferde gerçekleşmesi gerekmez; Eğer yavaş yavaş kod refactor.

Sorununuzu çözmek, ancak birlikte sadece grup benzer işlevlere ad alanları olarak sınıfları kullanıyorsanız, bir örneğini oluşturma yükünü önlemek için statik yöntemleri kullanmayı düşünün olmaz.

class Foo {

    static function bar() {

    }

}

Foo::bar()