Jump to content

TechnoDiver

Members
  • Posts

    203
  • Joined

  • Last visited

Posts posted by TechnoDiver

  1. Can someone give me a hand looping through this. I've been trying to make an array out of only the 'category fields for hours. Figured I'd ask for help before doing something I regret to my computer ->

    Quote

    DB Object ( [_pdo:DB:private] => PDO Object ( ) [_query:DB:private] => PDOStatement Object ( [queryString] => SELECT * FROM categories WHERE type = ? ) [_error:DB:private] => [_results:DB:private] => Array ( [0] => stdClass Object ( [id] => 1 [category] => public health [type] => top ) [1] => stdClass Object ( [id] => 2 [category] => environment [type] => top ) [2] => stdClass Object ( [id] => 3 [category] => global unrest [type] => top ) [3] => stdClass Object ( [id] => 4 [category] => military [type] => top ) [4] => stdClass Object ( [id] => 6 [category] => super powers [type] => top ) [5] => stdClass Object ( [id] => 7 [category] => technology [type] => top ) [6] => stdClass Object ( [id] => 8 [category] => human rights [type] => top ) [7] => stdClass Object ( [id] => 60 [category] => space race [type] => top ) [8] => stdClass Object ( [id] => 67 [category] => globalism [type] => top ) [9] => stdClass Object ( [id] => 87 [category] => government [type] => top ) ) [_count:DB:private] => 10 )

    I'm trying to make an array of all the values in each 'category' key

  2. Good evening, Phreaks. Quick question. I have this method here ->

    public function get($table, $where = [], $column = "*") {
            return $this->action("SELECT {$column}", $table, $where);
        }

    It works great as long as the call to it includes the $where array. I want both $where and $column to be optional here and $where to be an array when it's included.

    if I only use the $table parameter (which is the only one I want to be required). I keep getting a

    Quote

    Fatal error: Uncaught Error: Call to a member function count() on bool

    Could one of you fine folks please explain to me about this error and why I need the $where parameter when I want it to be optional. Thank you

  3. Hi, Phreaks, I'm stuck on something that maybe someone can help with

    on trying to send a user information to phpmyadmin I get this error ->

    Quote

    SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect string value: '\xD8,\x08Up\x92...' for column `qcic`.`users`.`salt` at row 1

    There's 2 problems here, as you can see. 1) I've got an invalid datetime format. 2) is obviously the incorrect string value on my salt value.

    here is the corresponding code ->

    <?php
    
    if($validation->passed()) {
      $user = new User();
      $salt = Hash::salt(32);
    
      try {
          $user->create(array(
              "username" => Input::get("usernane"),
              "password" => Hash::make(Input::get("password"), $salt),
              "email" => Input::get("email"),
              "salt" => $salt,
              "signup_date" => date_create('now')->format('Y-m-d H:i:s'),
              "role" => 2,
          ));
          $sent = true;
      } catch(Exception $e) {
          die($e->getMessage());
      }
    
    } else {
      $errors = $validation->errors(); 
    }

    It can be seen how I did both of them here. Additionally the Hash::salt method is here ->

    <?php
    
    public static function salt($length) {
            return random_bytes($length);
        }

    the column 'signup_date' is in my database as a datetime not null with 'none' as default.

    The column 'salt' is a VARCHAR(32) not null, 'none' as default

    Can anyone help me out with what I've done wrong, please. TIA

  4. 17 hours ago, kicken said:

    Your query method does not return anything, so $user will be NULL.

    I had already tried this.

    I tried return $this->_errors. It should have been just return $this; So now it works

    But it's interesting because the below change works with query() as it was - not returning anything

    <?php
    $user = DB::getInstance();//->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"));
    $user->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"));

    Which leads into another question of why? I have no idea why it works breaking the line up like this while query() doesn't have a return. Maybe someone here can shine some light on that.

    To the respondents suggesting something more simple, thanks for your responses. Solicited or not all advice is good, everyone has something to learn from.

    It is a bit more complex, yes, but it's a class not meant for a single project, it's me trying my hand at a very abstract database wrapper. There's not meant to be any sql statements in this class.

    Thanks for the responses phreaks. The answer was indeed to either 'return $this' in query() or for some obscure reason, that I'm hoping someone here will be able to answer, to leave query() alone and split that statement into 2 lines.

     

  5. 1 hour ago, kicken said:

    What is your code for DB::getInstance() and your query() methods?

    DB::getInstance() is ->

    <?php
    public static function getInstance() {
            if(!isset(self::$_instance)) {
                self::$_instance = new DB();
            }
            return self::$_instance;
        }

    query() is ->

    <?php
    public function query($sql, $params = array()) {
            $this->_error = false;
            if($this->_query = $this->_pdo->prepare($sql)) {
                $x = 1;
                if(count($params)) {
                    foreach($params as $param) {
                        $this->_query->bindValue($x, $param);
                        $x++;
                    }
                }
    
                if($this->_query->execute()) {
                    $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
                    $this->_count = $this->_query->rowCount();
                    echo "query success <br>";
                } else {
                    $this->_error = true;
                    echo "query fail";
                }
            }
        }

    when I run

    <?php
    $user = DB::getInstance()

    this is successful ->

    <?php
    if($user) {
        echo "success -> ";
        // echo $user;
    } else {
        echo "fail -> ";
        // echo $user;
    }

    when I make it ->

    $user = DB::getInstance()->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"));

    than this fails ->\

    if($user) {
        echo "success -> ";
        // echo $user;
    } else {
        echo "fail -> ";
        // echo $user;
    }

    But the echo in query() always comes back "query success"

    can't figure out why adding

    ->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"))

    collapses the methods

  6. Could someone explain to me why this connection/query succeeds

    <?php
    DB::getInstance()->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"));

    But when I do this it comes back as failed

    <?php
    $user = DB::getInstance()->query("SELECT username FROM users WHERE username=?", array("TechnoDiver"));
    
    if($user) {
        echo "success -> ";
    } else {
        echo "fail -> ";
    }

    like I said I ran tests for the DB->query in the query method and it comes back successfully. It's only when I try to assign it that it comes back failed. Why??

  7. Hi Freaks, I've been trying to put together subscribe functionality on a project. Been at it for hours and can't make any progress.

    The categories that a user is subbed to are stored in comma separated string in the database and pulled out into $_SESSION['user_subs']

    I have these 2 methods here to start ->

    <?php
    private function userSubscribed($cat_id) {
        $category = $this->getCategoryByID($cat_id);
        if(in_array($category, $_SESSION['user_subs'])) { 
            echo "user subscribed";
            return true;
        } else {  
            echo "user NOT subscribed"; 
            return false;       
        }
    }
    
    public function displaySubscribedButton($cat_id) {
        $subscribed = $this->userSubscribed($cat_id);
        if($subscribed) {
            $action_btn = "<td><a href='category_posts.php?cat_id=$cat_id' name='sub_btn' class='btn btn-secondary'>Unsubscribe</a>";
        } else {
            $action_btn = "<td><a href='category_posts.php?cat_id=$cat_id' name='sub_btn' class='btn btn-danger text-color-									primary'>Subscribe</a>";
        }
    
        return $action_btn;
    }

    They've both been well tested and I know they're working correctly.

    Then I have this one (which is the problem child) ->

    <?php
    public function updateSubscriptionCategory($cat_id, $username) {
        $category = $this->getCategoryByID($cat_id);
        $subscribed = $this->userSubscribed($cat_id);
    
        print_r($_SESSION['user_subs']);
    
        if($subscribed){
            unset($_SESSION['user_subs'][$category]);
            $subs = $_SESSION['user_subs'];
            $subscribed = false;
        } else {
            $new_sub = ",".$category;
            $subs = array_push($_SESSION['user_subs'], $new_sub);
            $subscribed = true;
        }
    
        $stmt = $this->conn->prepare("UPDATE ".User::$table." SET subs=? WHERE username=?");
    
        if($stmt) {
            $stmt->execute([$subs, $username]);
        } else {
            echo "you fucked up";
        }
    }

    I call it from the category file, here ->

    <?php require_once("assets/initializations.php"); 
    $post_obj = new Post($conn, $username);
    $cat_obj = new Category($conn, $username);
    
    $cat_id = $_GET['cat_id'];
    if(isset($_POST['sub_btn'])) {
        $cat_obj->updateSubscriptionCategory($cat_id, $username);
        // header("Location: category_posts.php?cat_id=$cat_id&cat_title=$cat_title");
    }

    but the page only reloads no changes are made not on the page nor in the db nor do I get any feedback, not from the 'print_r' or the else at the bottom. I feel like it's not even running this method. Was hoping that someone sees something that I've been missing. 8 hours in and I'm still not able to get it to work. TIA for all input

  8. 42 minutes ago, Strider64 said:

    Does it work in the parent class? If it doesn't then there is something wrong with self::$conn

    this static method is in a class with public methods and $this->conn is working fine. It's a quick method to take care a of quick need I don't want to have to instantiate an object just to use this quick method. Is there anything else I have to do inside the class to make it work as self::$conn? Like I said $this->conn is working fine everywhere else in the class

  9. I have this static method:

    public static function getIDByCategory($category) {
      $query = "SELECT top_cat_id FROM top_categories WHERE top_cat_title=?";
      $stmt = self::$conn->prepare($query); <-- line 89 from the error message
      $stmt->execute([$category]);
      $row = $stmt->fetch(PDO::FETCH_ASSOC);
      $cat_id = $row['top_cat_id'];
      return $cat_id;
    }

    I'm calling it like this from a different class:

    $cat_id = Category::getIDByCategory($category);

    and I'm getting this error:

    Quote

    Fatal error: Uncaught Error: Access to undeclared static property Category::$conn in /opt/lampp/htdocs/qcic/assets/class/Category.php:89

    I feel like I've followed all the rules. Could someone breakdown the mechanics of what is happening here?

  10. 1 hour ago, Barand said:

    fetchAll() returns an array of records. You want just the single record. Use fetch();

    Alright, so to understand you better - Does this mean that a fetchAll() on this query:

    $query = "SELECT * FROM users WHERE username = ?";

    would return all values in the table under the username column? So, all usernames in the table?

    Whereas fetch() returns the values in a specific row that the specific username is in?

  11. 26 minutes ago, kicken said:

    This is why I suggested earlier that you might be better off for now just dealing with PDO and drop the whole idea of having a Database class.  All your database class is managing to do so far is get in your way and confuse you.

    I've done that and am making a bit of progress. my config.php file is now light, slim and simple ->

    <?php
    
    ob_start();
    session_start();
    
    $timezone = date_default_timezone_set("America/Cancun");
    $whitelist = array('username', 'email', 'email2', 'password', 'password2');
    
    $db_host = "localhost";
    $db_user = "root";
    $db_password = "";
    $db_name = "qcic";
    
    $conn = new PDO("mysql:host={$db_host};dbname={$db_name}", $db_user, $db_password);
    
    ob_end_flush();

    I still have a lot of mysqli to change to PDO. But I've just run into another something. This is the start of my User class ->

    <?php 
    
        class User {
            private $conn;
            private $username;
    
            public function __construct($conn, $username) {
                $this->conn = $conn;
                $query = "SELECT * FROM users WHERE username='$username'";
     		    $statement = $this->conn->prepare($query);
                $statement->execute();
    
                $this->user_data = $statement->fetchAll(PDO::FETCH_ASSOC);
            }
    
            public function getUsername() {
                print_r($this->user_data);
                $username = $this->user_data['username'];
                return $username;
            }
    
            public function getRole() {
                $role = $this->user_data['role'];
                return $role;
            }

    You can see where I printed the array in getUsername for test purposes. This is the array ->

    Quote

    I'm getting these warnings ->

    Quote

    The keys I specified are exactly how they are as the DB columns, and we can both see that they're defined. So what is causing these error messages?

  12. 13 hours ago, kicken said:

    Your database class doesn't have a prepare method, that's why you get an error.

    You're right, it doesn't. This is my database class:

     class Database {
        private $dbhost = "localhost";
        private $dbuser = "root";
        private $dbpassword = "";
        private $dbname = "qcic";
        public $conn;
    
        public function __construct() {
    
            $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
            $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
    
        }     
    }

    I'm not sure what the prepare method would even consist of or how to implement it in this instance. I was just trying to create the connection. What would a prepare method in this class even do?

  13. 12 hours ago, kicken said:

    Your User class code is expecting to receive an instance of the PDO class.  That exists as the conn property on your Database class, referenced by $conn->conn.

    Thanks for all your responses and patience. My issue wasn't understanding the technical side that you were explaining (sometimes it is) in this specific instance I was having trouble with syntax, operators etc. I'm still trying to get a grasp of '->', '::' etc and how to move different types of data in the manner that needs to be used for that specific data type. Thanks for your help, I believe I've made it past that particular hiccup and will concentrate on learning and refactoring with PDO.. I'm sure we'll speak again. Have an awesome week

  14. 11 minutes ago, kicken said:

    You're missing a

    $conn = new Database();

    HaHa, that's funny because it brings us back to how I originally coded it which gave the error message that started this thread, and the roots of my confusion because this makes sense to me but doesn't work. I get

    Quote

    Fatal error: Uncaught Error: Call to undefined method Database::prepare() in /opt/lampp/htdocs/qcic/assets/class/User.php:10 Stack trace: #0 /opt/lampp/htdocs/qcic/assets/class/User.php(135): User->__construct(Object(Database), 'TechnoDiver') #1 /opt/lampp/htdocs/qcic/newsnet/assets/initializations.php(3): require('/opt/lampp/htdo...') #2 /opt/lampp/htdocs/qcic/newsnet/index.php(1): require('/opt/lampp/htdo...') #3 {main} thrown in /opt/lampp/htdocs/qcic/assets/class/User.php on line 10

    from

    <?php 
    
        class User {
            private $conn;
            private $username;
    
            public function __construct($conn, $username) {
                $this->conn = $conn;
                $query = "SELECT * FROM users WHERE username='$username'";
     		    $statement = $this->conn->prepare($query);
                $statement->execute();
                $username = $statement->fetchAll(PDO::FETCH_ASSOC);
    
            }
    ...........

    and we come full circle. I'm completely lost

    I tried this too

    $conn = new Database();
    $conn->conn;

    I feel cursed

  15. 45 minutes ago, kicken said:

    You're assigning the instance of PDO that you create to the conn property of your Database class.  To access if from code outside of the Database class (which requires the property to be public), you'd use $conn->conn

    ok, I get it, I think but from what you're saying this

    <?php
    
    class Database {
        private $dbhost = "localhost";
        private $dbuser = "root";
        private $dbpassword = "";
        private $dbname = "qcic";
        public $conn;
    
        public function __construct() {
              $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
              $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
        }     
    }
    
    ob_start();
    session_start();
    
    $timezone = date_default_timezone_set("America/Cancun");
    $whitelist = array('username', 'email', 'email2', 'password', 'password2');
    $conn->conn; //this bit here
    ob_end_flush();

    Should get that $conn variable assigned and I can't get that damn $this->conn variable assigned to $conn for anything that I do. I'm stupified, I feel like everything I thought I understood is shattered. Why isn't $this->conn passing to $conn??

    I need a spoiler or something lol, I'm lost

  16. 42 minutes ago, Barand said:

    How would you code this sequence?

    1. Create Database object
    2. Create User object passing the database connection and username.

    I've put mine in my config file because it's outside of my root directory ( the Database class). It passes the required data (localhost, db name, password, username) and returns the connection data. Instantiate the Class

    $conn = new Database();

    and that contains the connection data ($this->conn) from ->

    class Database {
        private $dbhost = "localhost";
        private $dbuser = "root";
        private $dbpassword = "";
        private $dbname = "qcic";
        public $conn;
    
        public function __construct() {
            try {
                $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
                $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
            } catch(PDOException $exception) {
                die("DB connection failed: " . $exception->getMessage());
            }
    
            return $this->conn;
        }     
    }

    That then is loaded by load.php ->

    <?php require_once($_SERVER['DOCUMENT_ROOT'] . '/../config/config.php');

    and how I had it before this fiasco we're talking about now is that all is passed into initializations.php ->

    <?php
    require("../load.php");
    require("../assets/class/User.php");
    require("../assets/class/Category.php");
    require("../assets/class/Post.php");
    require("../assets/class/Comment.php");
    require("../assets/class/Image.php");
    
    // if(session_status() === PHP_SESSION_NONE) {
    //     $username = "";
    // } else {
    //     $username = $_SESSION['username'];
        
    // }
    
    $user_obj = new User($conn, $username);
    $username = $user_obj->getUsername();
    $role = $user_obj->getRole();
    
    $cat_obj = new Category($conn, $username);

    Which is required at the top of every page in the site. I hope that answers your question, I really appreciate your responses, I'm lost right now. This makes sense to me and worked great until today. I just can't wrap my head around what is happening to that $conn

     

    EDIT: and now I'm trying to get my head around kicken saying that constructors can't return values and trying to figure out how to acces $this-conn in the instantiation AND I'm not even sure if that's the issue, lol

  17. 9 minutes ago, kicken said:

    I would suggest for learning PDO that you drop the entire Database class and just deal with PDO directly.  Once your more familiar with PDO and OOP in general you can look into creating a database class if you find a need for one.  The PDO is pretty decent already, there's not a lot of benefit to creating your own class on top of it.

    So, I actually just started learning PDO today because it's been recommended so many times before. I thought that I finally had a good enough grasp of PHP to leave the MYSQL that I started with. I've written many working classes so far but have refrained from passing too much data directly between them. All this worked great until I started the database class but it was the first thing the tutorial I was watching started with so I decided to give a shot at applying it to my present project

  18. 6 minutes ago, Barand said:

    The question was about how you instantiate the user object

    ah, ok, so it's like this for now. because I haven't finished the login and I needed to switch between users with different roles. This will obviously change eventually. ATM it's at the bottom of the User.php class page

    $userindex = 0;
    $userarray = array("TechnoDiver", "jwick", "ChesterCheetah", "AfghanStan");
    $username = $userarray[$userindex];
    $user_obj = new User($conn, $username); 

    again, this was working fine until I started trying to put config.php in a class. That's where everything went pear shaped

     

    EDIT: the User class constructor was in mysql and I really thought when I changed it things would work but it seems I haven't understood something. Because I feel it's not reading the $conn variable in config.php. Again this is a direct result of the database class because $conn was passing fine earlier too.

  19. 22 minutes ago, ginerjm said:

    Of course what is the point of trying to switch to PDO ( a good move BTW) if you are still going to use mysql code in other parts of your script?

    I'm not staying with mysql. I'm working on changing everything over right now, having some problems with it as you can see

    <?php
    
    class Database {
        private $dbhost = "localhost";
        private $dbuser = "root";
        private $dbpassword = "";
        private $dbname = "qcic";
        public $conn;
    
        public function __construct() {
            try {
                $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
                $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
            } catch(PDOException $exception) {
                die("DB connection failed: " . $exception->getMessage());
            }
    
            return $this->conn;
        }     
    }
    
    ob_start();
    session_start();
    
    $timezone = date_default_timezone_set("America/Cancun");
    $whitelist = array('username', 'email', 'email2', 'password', 'password2');
    $table = 'users';
    $conn = new Database();
    ob_end_flush();

    This is my DB code in config.php. The following is my __construct code for User.php

    <?php 
        class User {
            private $conn;
            private $username;
    
            public function __construct($conn, $username) {
                $this->conn = $conn;
                $query = "SELECT * FROM users WHERE username='$username'";
     		    $statement = $this->conn->prepare($query);
                $statement->execute();
                $username = $statement->fetchAll(PDO::FETCH_ASSOC);
                return $username;
    
            }

    and it's returning this error ->

    Quote

    Fatal error: Uncaught Error: Call to undefined method Database::prepare() in /opt/lampp/htdocs/qcic/assets/class/User.php:11 Stack trace: #0 /opt/lampp/htdocs/qcic/assets/class/User.php(137): User->__construct(Object(Database), 'TechnoDiver') #1 /opt/lampp/htdocs/qcic/newsnet/assets/initializations.php(3): require('/opt/lampp/htdo...') #2 /opt/lampp/htdocs/qcic/newsnet/index.php(1): require('/opt/lampp/htdo...') #3 {main} thrown in /opt/lampp/htdocs/qcic/assets/class/User.php on line 11

    line 11 that it refers to is ->

    $statement = $this->conn->prepare($query);

    I'm not exactly sure how to read this message but it seems to me that the Database object is being passed in __construct rather than the $conn value that it returns (that I thought it returned). I'm not sure if that's the case, I have no idea. I thought I understood it better and am really happy I committed everything before starting these changes, because I've made a mess of things. Why isn't the $conn variable passing to these other classes, it's public??

  20. Just now, TechnoDiver said:

    I'm returning $this->conn like this

    public function __construct() {
            try {
                $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
                $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
            } catch(PDOException $exception) {
                die("DB connection failed: " . $exception->getMessage());
            }
    
            return $this->conn;
        }

    and instantiating like this ->

    ob_start();
    session_start();
    
    $timezone = date_default_timezone_set("America/Cancun");
    $whitelist = array('username', 'email', 'email2', 'password', 'password2');
    $table = 'users';
    $conn = new Database();
    ob_end_flush();

    $this->conn needs to be made public even though it's the return value?? I feel not, but I'm not sure I understood you

    And there's also this issue, I wasn't sure about that. But I'll have to replace a lot of code before I'll know anything.

     

  21. 28 minutes ago, Barand said:

    What are you passing to new User()? the $db_obj or the $db_obj->conn. (it would need to be public for that to work BTW)

    I'm returning $this->conn like this

    public function __construct() {
            try {
                $dsn = "mysql:host=" . $this->dbhost . ";dbname=" . $this->dbname;
                $this->conn = new PDO($dsn, $this->dbuser, $this->dbpassword);
            } catch(PDOException $exception) {
                die("DB connection failed: " . $exception->getMessage());
            }
    
            return $this->conn;
        }

    and instantiating like this ->

    ob_start();
    session_start();
    
    $timezone = date_default_timezone_set("America/Cancun");
    $whitelist = array('username', 'email', 'email2', 'password', 'password2');
    $table = 'users';
    $conn = new Database();
    ob_end_flush();

    $this->conn needs to be made public?? I feel not, but I'm not sure I understood you

    32 minutes ago, Barand said:

    You can't use a mysqli_xxx() call with a PDO connection.

    And there's also this issue, I wasn't sure about that. But I'll have to replace a lot of code before I'll know anything.

  22. 1 minute ago, ginerjm said:

    How are YOU connecting $conn to another class?  Are you passing it in your calls to their methods or setting a class property?

    class property ->

    <?php 
    
        class User {
    
            private $conn;
            private $username;
    
            public function __construct($conn, $username) {
                $this->conn = $conn;
                $query = mysqli_query($this->conn, "SELECT * FROM users WHERE username='$username'");
     		    return $this->user = mysqli_fetch_array($query);
            }
          
    ........

    but these classes are in mysql and I made the connection in PDO. Would that be the cause??

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.