1

すべてのコードを mysql から PDO に変更していますが、少し問題があります。ここにある多くの情報とnettusのチュートリアルを読みましたが、コードが機能しない理由をまだ理解できません。

以下はlogin.php PHPです。ログインを押すと、Userクラスを開いてログインを開始する必要があります。

<?php

    require_once('../global.php');
    require_once('../assets/header.php');
    if (isLogged())
    {
        header("Location: $website_domain");
        exit;
    }

    if (isset($_POST['submit']))
    {
        $username = $_POST['username'];
        if(empty($_POST['password']))
        {
            $password == "";
        }
        else
        {
            $password = md5($_POST['password'].$_POST['username']);
        }

        $object = new User();
        $object->Login($username,$password);

    }

?>

これは私が受け取っているエラーです: Fatal error: Call to a member function prepare() on a non-object in /home/astonish/public_html/labs.site.com/lock/includes/classes/user.class.php on line 32

私の User クラスを見る必要がある場合は、質問してください。皆さんが見る必要があるのはエラーだけである場合、これをコードで埋めたくありません。

User.class.php

<?php

    require_once('connection.php');

    // new data
    $ip    = $_SERVER['REMOTE_ADDR'];
    $hour  = date('h');
    $month = date('m');
    $date  = dateTime();

    class User
    {
        private $db;
        public function _construct() 
        {
            $this->db = new Connection();
            $this->db = $this->db->dbConnect(); 
        }

        public function Login($name, $pass) 
        {
            if(empty($name))
            {
                echo "Please input a username";
            }
            elseif(empty($pass))
            {
                echo "Please input a password";
            }
            elseif(!empty($name) && !empty($pass))
            {
                $st = $this->db->prepare("select * from users where username=? and password=?");
                $st->bindParam(1, $name);
                $st->bindParam(2, $pass);
                $st->execute();

                if($st->rowCount() == "1")
                {

                    // Delete failed attempts
                    $st = $db->prepare('DELETE FROM failedLogins WHERE ip = :ip');
                    $st->bindParam(':ip', $ip); // this time, we'll use the bindParam method
                    $st->execute();

                    // Get status of user
                    $result = $st->fetch(PDO::FETCH_ASSOC);
                    $result->status;

                    if ($fetch['status']==1)
                    {
                        $error = 'Your account is pending email.';
                    }
                    else if ($fetch['status']==2)
                    {
                        $_SESSION['main'] = md5(sha1($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'].$fetch['id']));
                        $_SESSION['uid'] = base64_encode($fetch['id']);

                        header("Location: $website_domain");
                        exit;
                    }
                    else if ($fetch['status']==5)
                    {
                        $error = 'Your account is inactive or was denied.';
                    }
                    else
                    {
                        $error = 'Invalid account status.';
                    }
                }
            }
            else
            {   
                $st = $this->db->prepare("INSERT INTO `failedLogins` (ip,hour,month,date) VALUES (:ip,:hour,:month,:date)");
                $st->execute(array(':ip'=>$ip, ':hour'=>$hour, ':month'=>$month, ':date'=>$date));

                echo  'The username or password entered is invalid.';
            }
        }

    }

?>

接続.php

class Connection 
    {
        public function dbConnect() 
        {
            return new PDO("mysql:host=localhost;dbname=astonish_viral", $mysql_user, $mysql_pass);
            /*try 
            {
                $db = new PDO("mysql:host=localhost;dbname=astonish_viral", $mysql_user, $mysql_pass);
                echo 'Connected to database';
            }
            catch(PDOException $e)
            {
                echo 'ERROR: ' . $e->getMessage();
            }*/
        }
    }

新しいエラー: 以下のエラーが表示されるようになりました

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user ''@'localhost' (using password: NO)' in /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php:12 Stack trace: #0 /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php(12): PDO->__construct('mysql:host=loca...', NULL, NULL) #1 /home/astonish/public_html/labs.site.com/lock/includes/classes/user.class.php(17): Connection->dbConnect() #2 /home/astonish/public_html/labs.site.com/lock/account/login.php(23): User->__construct() #3 {main} thrown in /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php on line 12
4

2 に答える 2

1

これは、コンストラクターのスペルを間違えたタイプミスです。メソッド名のスペルが間違っているため、'your' コンストラクターは呼び出されないため、$this->db は初期化されません。

PHP でコンストラクターを定義するには、次の 2 つのオプションがあります。

public function __construct()

コンストラクタとして機能するには、 2 つのアンダースコアが必要であることに注意してください。あなたが持っている別のオプションは、クラスのようなコンストラクターメソッドに名前を付けることです

public function User()

クラス名を変更してもコンストラクタ名を変更する必要がないため、最初のスタイルをお勧めします。


コードに別の構文エラーがあります。User.php の 41 行目を次のように置き換えます。

$st = $this->$db->prepare('DELETE FROM failedLogins WHERE ip = :ip');

(あなたは行方不明$this)


質問の更新に別のエラーを投稿しました。Connection クラスのどこで を定義し$mysql_userていますか?$mysql_pass

于 2013-01-30T00:09:01.360 に答える
1

私の推測では、オブジェクト (オブジェクトを作成したと仮定) はメソッドPDO内のスコープ内にありません。User::Login()

ここでいくつかの仮定をとりますが、たとえばPDOでオブジェクトを作成するとしましょうglobal.php

$pdo = new PDO('mysql:host...');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Userこれをクラス内に登録する必要があります。

class User {
    private $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    // etc

User次に、メソッド内でこのオブジェクトを使用できます。

public function Login($username, $password) {
    $stmt = $this->pdo->prepare('SELECT ... ');
    $stmt->execute(array(
        'username' => $username,
        'password' => $password
    ));

    // etc
}

Userクラスを作成するときはPDO、コンストラクターを介してインスタンスを渡します

$object = new User($pdo); // pass $pdo object created in global.php
$object->Login($username, $password);

アップデート

$this->この行の接頭辞が単に欠落しているようです

// Delete failed attempts
$st = $db->prepare(...

する必要があります

$st = $this->db->prepare(...

補遺

クラスをインスタンス化するたびに接続を作成する必要はないと思いますUser。代わりに、接続を個別に作成し、コンストラクターを介して注入する必要があります。このようにして、オブジェクトを再利用できPDOます。

また、あなたのConnectionクラスは冗長に見えます。PDO1 種類のデータベースのみをサポートしている場合は、抽象化レイヤーにラップせずに使用できる優れたクラスです。

于 2013-01-29T23:40:08.103 に答える