* RECURSION *有多糟糕?

时间:2015-12-08 06:31:40

标签: php class recursion

我想创建一个App对象,其中包含我的数据库,清理程序和用户的对象。这样,我可以简单地使用单个App对象,而不是单独调用所有这些不同的对象,因为我的大多数其他对象将需要大多数(如果不是全部)这些对象用于其中的方法。

User对象将来会有CRUD方法,因此可以更改其属性,因此,我不想要包含CRUD方法的单独对象和处理用户身份验证的对象,原因是我不希望在两个单独的类中具有完全相同的对象属性,因为技术上完全相同的对象。

那就是说,这种递归发生有多糟糕(请参阅App类中如何使用User对象)?我是否应该采取措施对此进行不同的编码?这是一个大问题吗?请记住,将为CRUD方法调用此User类,因此登录的用户只需使用不同的变量名称并实例化其新实例,就可以通过此对象更改任何其他用户

class App {
    public $db;
    public $sanitizer;
    public $user;
    public $settings;

    function __construct () {
        // create $app->db object
        $db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);      
        $this->db = $db;

        // create $app->sanitizer object
        $this->sanitizer = new Sanitizer();

        // set $app->settings
        $this->setSettings();

        // create $app->user object
        $this->user = new User($this); // NOTE THE RECURSION HERE
        $this->user->setIsSignedIn();

        if ($this->user->is_signed_in) {
            $this->user->populateById();
        }
    }

    function setSettings () {
        $sql = 'select * from `settings`';
        $stm = $this->db->prepare($sql);
        $stm->execute();
        $res = $stm->fetchAll();

        if ($res) {
            $res = $this->sanitizer->action('sanitize', $res);

            foreach ($res as $r) {
                $this->settings[$r['key']] = $r['value'];
            }
        }
    }
}

class User {
    public $app;
    public $id;
    public $username;
    public $password;
    public $token;
    public $is_signed_in = false;

    function __construct ($app) {
        $this->app = $app; // AGAIN, *RECURSION*
    }

    function populateByPost () {        
        foreach ($_POST as $k => $v) {
            if (property_exists($this, $k)) {
                $this->$k = $v;
            }
        }
    }

    function populateById () {
        $sql = 'select * from `users` where `id`=:id';
        $stm = $this->app->db->prepare($sql);
        $stm->bindParam(':id', $this->id);
        $stm->execute();
        $res = $stm->fetch();

        if ($res) {
            $res = $this->app->sanitizer->action('sanitize', $res);

            foreach ($res as $k => $v) {
                $this->$k = $v;
            }
        }
    }

    function credentialsValid () {
        $sql = 'select * from `users` where `username`=:username';
        $stm = $this->app->db->prepare($sql);
        $stm->bindParam(':username', $this->username);
        $stm->execute();
        $res = $stm->fetch();

        if ($res) {
            if (password_verify($this->password, $res['password'])) {
                $this->id = $res['id'];

                return true;
            }
        }

        return false;
    }

    function createToken () {
        $this->token = password_hash($this->id.'|'.$this->username.'|'.$this->password, PASSWORD_DEFAULT);

        $sql = 'insert into `user_tokens` (`id_user`, `token`) values (:id_user, :token)';
        $stm = $this->app->db->prepare($sql);
        $stm->bindParam(':id_user', $this->id);
        $stm->bindParam(':token', $this->token);
        $stm->execute();
    }

    function setSessionVars () {
        $_SESSION['id_user'] = $this->id;
        $_SESSION['token'] = $this->token;

        if (isset($_POST['remember_me'])) {
            setcookie('id_user', $this->id, time() + 31556926, '/');
            setcookie('token', $this->token, time() + 31556926, '/');
        }
    }

    function setIsSignedIn () {
        if (isset($_COOKIE['id_user'])) {
            $id_user = $_COOKIE['id_user'];
            $token = $_COOKIE['token'];
        }
        else if (isset($_SESSION['id_user'])) {
            $id_user = $_SESSION['id_user'];
            $token = $_SESSION['token'];
        }

        if (isset($id_user)) {
            $sql = 'select * from `user_tokens` where `id_user`=:id_user and `token`=:token';
            $stm = $this->app->db->prepare($sql);
            $stm->bindParam(':id_user', $id_user);
            $stm->bindParam(':token', $token);
            $stm->execute();
            $res = $stm->fetch();

            if ($res) {
                $this->id = $res['id_user'];
                $this->is_signed_in = true;
            }
        }
    }

    function signOut () {
        $_SESSION['id_user'] = '';
        $_SESSION['token'] = '';

        session_destroy();

        if (isset($_COOKIE['id_user'])) {
            setcookie('id_user', '', time() - 1, '/');
            setcookie('token', '', time() - 1, '/');
        }
    }

    // CRUD METHODS TO BE ADDED HERE LATER
}

显然,当我print_r App对象时,它告诉我由于App->user构造中的代码,App对象中存在递归。

同样,我只是好奇,如果这是一个非常糟糕的事情,我绝对应该重新编码。任何见解将不胜感激。

0 个答案:

没有答案