-
Posts
203 -
Joined
-
Last visited
Posts posted by TechnoDiver
-
-
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
QuoteFatal 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
-
Switching from hash() to password_hash() and not using a salt resolved both issues. Question though, does password_hash() also salt the hash or is that something I should still do??
-
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 ->
QuoteSQLSTATE[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
-
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.
-
31 minutes ago, Solar said:
Should be just this, no?
public function query($sql, $params) {
doing it like that means that $params is required. The way I did it means that $params can be there or not
- 1
-
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
-
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??
-
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
-
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
-
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:
QuoteFatal 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?
-
Ok, thank you for your responses. They were very helpful
-
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?
-
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 ->
QuoteArray ( [0] => Array ( [id] => 1 [firstname] => Some [lastname] => One [username] => TechnoDiver => technodiver@somemail.com [password] => xxxxxxx [signup_date] => 2021-08-08 [profile_pic] => the_original.png [num_posts] => 0 [num_likes] => 0 [user_closed] => [friend_array] => [role] => admin [subs] => main ) )
QuoteThe 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?
-
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?
-
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
-
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
QuoteFatal 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
-
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
-
42 minutes ago, Barand said:
How would you code this sequence?
- Create Database object
- 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
-
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
-
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.
-
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 ->
QuoteFatal 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??
-
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.
-
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.
-
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??
Looping through an stdClass Object
in PHP Coding Help
Posted
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 ->
I'm trying to make an array of all the values in each 'category' key