Creating, Returning & Using Objects in PHP - php

I have a set of functions:
One creates the connection, the others do different kinds of database interaction using that function.
I am retrieving the error;
Call to undefined method mysqli::execute()
this is telling me that I am failing to send the object through correctly, I have done some research but failed to find examples;
<?php
function con(){
$mysqli = new Mysqli("localhost","user","pass","image_blog");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}else{
return $mysqli;
}};
function getAll(){
$mysqli = con();
$stmt = $mysqli->prepare("SELECT * FROM posts");
$stmt = $mysqli->execute(); <--- ERROR HERE
$stmt = $mysqli->get_result();
$stmt = $mysqli->close();
while($row = mysqli_fetch_array($stmt, MYSQL_ASSOC)) {
echo "Username: " . $row["image"];
echo "Username: " . $row["title"];
echo "Username: " . $row["text"];
echo "Username: " . $row["up"];
echo "Username: " . $row["date"];
}
};
function anotherFunction(){
}
function yetAnotherFunction(){
}

you should execute the statement ($stmt) it self not the $mysqli
$stmt->execute();
also consider using PDO class in the futur as it makes things mush easier

I see what that you're trying to achieve a connection function with your mysqli. Rather than connecting from each function individually. As Mr. Smith has mentioned, you've declared the variable $stmt like:
$stmt = $mysqli->prepare('SELECT * FROM posts');
This is incorrect as a prepared statement doesn't return data to be used in the variable, hence your error.
Another method would be to use classes, and yet another more advanced method would be to extend the mySQLi class.
Class myClass{
protected $dbh;
public function __construct(){
$this->dbh=new mysqli('','','','');
}
public function getAll(){
$this->dbh->prepare('SELECT * FROM posts');
$this->dbh->execute();
$this->dbh->bind_result($image,$title,$text,$up,$date);
while($this->dbh->fetch()){
echo"Username:".$image;
//and so on
}
$this->dbh->close();
}
public function anotherFunction(){
}
public function yetAnotherFunction(){
}
}
If you haven't used classes before you now need to create an instance of the class:
$databaseUser = myClass();
And to start your function:
$databaseUser->getAll();

It should be
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
$mysqli->close();
Instead of
$stmt = $mysqli->execute();
$stmt = $mysqli->get_result();
$stmt = $mysqli->close();
See official docs (examples too).

Related

PHP Class Parameters used twice

I am new to OOP, and I am switching all of my websites code to it! I am currently writing a class that grabs a user's information, and will eventually update it.
The code I am using is below:
<?php
require("C:\wamp\www\postin'\db_connection.php");
session_start();
class user {
public function __construct($userid, $connection, $information) {
$this->userid = $userid;
$this->connection = $connection;
$this->information = $information;
}
public function user_information($userid, $connection, $information) {
$query = "SELECT * FROM users WHERE id = :id";
$params = array(':id' => $userid);
try{
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);
}
catch(PDOException $ex){
echo ("Failed to run query: " . $ex->getMessage());
}
$columns = $stmt->fetch();
return $columns["$information"];
}
}
$username = new user($_SESSION["logged_in"], $connection, "username");
echo $username->user_information($_SESSION["logged_in"], $connection, "username");
?>
Now as you can see on the last two lines of code (one from the end) I have to use the parameters twice. Basically the first parameter says what the ID is, second says what the $connection is, and the third is what I want to grab from the database. So what am I doing wrong? Did I define something I did not need to?
EDIT
Would the following be valid as well?
<?php
require("C:\wamp\www\postin'\db_connection.php");
session_start();
class user {
public function user_information($userid, $connection, $information) {
$query = "SELECT * FROM users WHERE id = :id";
$params = array(':id' => $userid);
try{
$stmt = $connection->prepare($query);
$result = $stmt->execute($params);
}
catch(PDOException $ex){
echo ("Failed to run query: " . $ex->getMessage());
}
$columns = $stmt->fetch();
return $columns["$information"];
}
}
$username = new user();
echo $username->user_information($_SESSION["logged_in"], $connection, "username");
?>
Like is this in-properer, or wrong...?
If the user class has all the information it needs as data members, then user_information doesn't need to take any arguments:
public function user_information() {
$query = "SELECT * FROM users WHERE id = :id";
$params = array(':id' => $this->userid);
try{
$stmt = $this->connection->prepare($query);
$result = $stmt->execute($params);
}
catch(PDOException $ex){
echo ("Failed to run query: " . $ex->getMessage());
}
$columns = $stmt->fetch();
return $columns[$this->information];
}
Since you have a lot of questions about the way a class works and about OOP I will try to give you a little direction.
There is no standard way of building your class. You are the one that decides what goes where in terms of what belongs to the class and what needs to be injected. This is just to tell you that you cannot pin yourself down. You need to get a feel for it and build a logic.
I took your class and rebuild it some with added comments. Hope that will help you some. Good luck!
<?php
require ("C:\wamp\www\postin'\db_connection.php");
session_start();
class user {
public $dbconnection;
public function __construct($connection) {
/**
* Your user class interacts with the database.
* Inject the connection here and set your
* global class variable.
*/
$this -> dbconnection = $connection;
}
public function user_information($userid, $column) {
/**
* The userid and column are specific for this
* method action. No need to set these variables
* in the global scope of the class.
*/
$query = "SELECT" . $column . " FROM users WHERE id = :id";
$params = array(':id' => $userid);
try {
$stmt = $this -> dbconnection -> prepare($query);
$stmt -> execute($params);
} catch(PDOException $ex) {
echo("Failed to run query: " . $ex -> getMessage());
}
$result = $stmt -> fetch();
return $result;
}
}
$username = new user($connection);
echo $username -> user_information($_SESSION["logged_in"], $information);
?>

php mysqli "No database selected" using class

When I'm using mysqli without class it's going ok:
index.php
require_once(dirname(__FILE__) . '/config.php');
$mysqli = new mysqli($hostname, $username, $password, $dbname);
$queryText = "SELECT * FROM User";
if($query = $mysqli->query($queryText)) {
$results = $query->fetch_array();
echo $results['userId'];
} else {
echo "Error ";
echo $mysqli->errno . " " . $this->mysqli->error;
}
?>
But when I start using mysqli with class something goes wrong. connectDB doesn't give any error, so i get connected to DB. But then when trying do any query it give me "No database selected error"
Result of index.php is: Error 1046 No database selected
index.php
<?php
require_once(dirname(__FILE__) . '/banana.php');
$banana = new Banana(1);
if ($banana->connectDB()) {
$banana->doQuery();
}
?>
banana.php
<?php
require_once(dirname(__FILE__) . '/config.php');
class Banana {
private $mysqli, $userId, $query;
function __construct($userId) {
$this->userId = $userId;
}
function __destruct() {
$this->mysqli->close();
}
public function connectDB() { // Подключение к БД
$this->mysqli = new mysqli($hostname, $username, $password, $dbname);
if ($this->mysqli->connect_errno) {
echo "Error (" . $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error;
return false;
}
return true;
}
public function doQuery() {
$queryText = "SELECT * FROM User";
if($this->query = $this->mysqli->query($queryText)) {
$results = $query->fetch_array();
echo $results['userId'];
} else {
echo "Error ";
echo $this->mysqli->errno . " " . $this->mysqli->error;
}
}
?>
So it's very frustrating. I'm about 2 weeks in php, but can't find answer for couple days. I guess the answer is obvious but I can't see it.
Thank you for your time and patience.
One of the first problems you will encounter when you run your script is here:
public function connectDB() { // Подключение к БД
$this->mysqli = new mysqli($hostname, $username, $password, $dbname);
Note that all 4 variables you are using in your function call ($hostname, etc.) are undefined in the scope of the method.
There are several ways you can solve this:
Pass the variables as parameters to the method:public function connectDB($hostname, ...
Pass the necessary variable to your class constructor and set configuration properties in your class that you can use later on;
Use constants instead of variables;
Declare your variables global.
I would recommend one of the first 2 and definitely not the last one.
You can read more in the php manual about variable scope.
It looks like you are a copy'n'paste victim. In doQuery() change:
if($this->query = $this->mysqli->query($queryText)) {
$results = $query->fetch_array();
To:
if($this->query = $this->mysqli->query($queryText)) {
$results = $this->query->fetch_array();

Fatal error: Using $this when not in object context even whilst in object

I'm getting this error when calling my database class and running a query function.
Here is my class:
class dbConnect {
public $mysqli = null;
public function __construct() {
$this->mysqli = new mysqli( "localhost", "root", "pass", "database" );
if ($this->mysqli->connect_errno)
{
echo "Error MySQLi: ("&nbsp. $this->mysqli->connect_errno
. ") " . $this->mysqli->connect_error;
exit();
}
$this->mysqli->set_charset("utf8");
}
public function __destruct() {
$this->closeDB();
}
public function runQuery($qry) {
$result = $this->mysqli->query($qry);
return $result;
}
Here is my page:
$db = new dbConnect();
$insert = "INSERT INTO `users` (`username`,`password`,`email`,`ip`,`date`) VALUES ('$username','$pw','$email','$ip','$time')";
$db->runQuery( $insert ) or die("Error MySQLi: ("&nbsp. $db->mysqli->connect_errno . ") " . $db->mysqli->connect_error);
EDIT:
I'm now getting the error Dbr`0
In the last line in the die you are not in the object.
Change this:
$db->runQuery( $insert ) or die("Error MySQLi: ("&nbsp. $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error);
To this:
$db->runQuery( $insert ) or die("Error MySQLi: ("&nbsp. $db->mysqli->connect_errno . ") " . $db->mysqli->connect_error);
I would, however, recommend you creating a method to fetch the error instead of accessing your database object ($db->mysqli) directly.
In your or die statement you forgot a $this, replace it with $db
I dont see any closeDB function in your class that you called it in the __destruct() function like this: $this->closeDB();
also replace $this->mysqli->connect_errno with $db->mysqli->connect_errno in your query!

using class method to pull database info

Overview: I have a function that is supposed to pull a row of the db based on its id number
Problem: It seems my function is returning, but it isn't returning anything.
Details:
-I have 2 different files used here: db_class.php and character_pull.php
-Also I have a database that contains 1 table (characters) that does contain column "id"
-there are echo lines for debugging. I will give what the output is.
character_pull.php:
<?php
include "db_class.php";
echo "made it out here1";
$classobject = new db_class();
echo "made it out here2";
$results = $classobject->getPlayerStats("1");
print_r($results);
echo "made it out here3";
$id = "id: " . $results['id'];
$name = "name: " . $results['charname'];
$strength = "strength: " . $results['strength'];
$defense = "defense: " . $results['defense'];
$health = "health: " . $results['health'];
$level = "level: " . $results['level'];
$type = "type: " . $results['type'];
$experience = "experience: " . $results['experience'];
echo"<br/>";
echo "made it out here4";
?>
db_class.php:
<?php
include "database_connect.php";
class db_class{
public function getPlayerStats($id){
echo "<br/>" . "making it in class1";
$query = "SELECT * FROM characters WHERE id = $id";
$result = mysqli_query($query);
return $char = mysqli_fetch_array($result);
$result ->close();
}
}
?>
the output I receive when I run the page is this:
made it out here1made it out here2 making it in class1made it out
here3 made it out here4
I have tried several things to fix this, but am having trouble figuring out what is wrong.
I know that this is probably extremely sloppy and primitive, but try not to laugh too hard and maybe you can help me out :P. Thanks in advance.
You have a number of issues here.
It seems your DB class is quite incomplete. To me, if I am creating a class to represent a DB connection and various operations I am going to make that connection in that class, not via some include (where I assume the connection is happening). The here is that the include will only occur conditionally if your code hits that line. In this case, since you have that include outside any actual function in the class (like a constructor) it will never be called.
I would suggest something like this to resolve this:
class db_class {
protected $mysqli;
private $db_host = 'your_db_host';
private $db_user = 'your_db_user';
private $db_password = 'your_db_password';
protected $db_name = 'default_db_name';
public __construct($db_host = NULL, $db_user = NULL, $db_password = NULL, $db_name = NULL) {
if (!empty($db_host)) {
$this->db_host= $db_host;
}
// validate other parameters similarly
$mysqli = new mysqli($this->db_host, $this->db_use, $this->db_password, $this->db_name);
if($mysqli->connect_error) {
throw new Exception('Connect Error: ' . $mysqli->connect_errno . ', ' . $mysqli->connect_error);
} else {
$this->mysqli = $mysqli;
}
}
// other class methods
}
You now have an object representing a mysqli connection store in $this->mysqli.
Your getPlayerStats() method might now look like
public function getPlayerStats($id) {
if(empty($id)) {
throw new Exception ('An empty value was passed for id');
}
// verify this is integer-like value
$id = (string)$id;
$pattern = '/^\d+$/';
if (!preg_match($pattern, $id) !== 1) {
throw new Exception ('A non-integer value was passed for id');
}
$id = (int)$id;
$query = "SELECT id, name, strength, defense, level, health, type, experience FROM characters WHERE id = :id";
$stmt = $this->mysqli->prepare($query);
$stmt->bind_param('i', $id);
$result = $stmt->execute();
if (false === $result) {
throw new Exception('Query error: ' . $stmt->error);
} else {
$obj = new stdClass();
$stmt->bind_result($obj->id, $obj->name, $obj->strength, $obj->defense, $obj->level, $obj, health, $obj->type, $obj->experience);
$stmt->fetch();
$stmt->close();
return $obj;
}
}
Note I used prepared statements here, which, you should get used to using as it is really best practice for querying databases. Note also I have added in handling of error cases all throughout the code. You should get in the habit of doing this, as it will making debugging much easier.
Just a guess but I would move this above the class name:
<?php
include "database_connect.php";
class db_class{

php with two class

my sample is good or not?
I have a good connection to the database, or too should be in the class?
Thanks
<?php
mysql_connect('localhost','root','admin');
mysql_select_db('test');
class UserDisplay
{
function getDisplayName()
{
$sql = 'select first_name, last_name, display_name from users where user_id = "3"';
$results = mysql_query($sql);
$row = mysql_fetch_array($results);
$this->user_id = $user_id;
return $this->user_id;
}
}
class UserInsert
function InsertName($name)
{
mysql_query("INSERT INTO Persons (first_name)VALUES ('".$name."')");
}
}
$userD = new UserDisplay();
echo "User known as: " . $userD->getDisplayName() . "\n";
$userI = new UserInsert();
$userI->InsertName("Peter");
?>
You should merge those classes into a single User class, then select the user array from the database in the constructor and store it in a class variable.
You would also ideally pass in the mysql connection to that class so that it doesn't always just use the default connection. The mysql functions all have a "link identifier" parameter, and it's considered good practice to use it if you aren't using an OO interface (like mysqli's OO class).
Probably be better off just making them functions, instead of wrapping them up in classes. Extract all of it, except the last into it's own php file. You forgot to extract display name from $user
// myFunctions.php
<?php
function connectDb() {
mysql_connect('localhost', 'root', 'admin');
mysql_select_db('test');
}
function closeDb() {
mysql_close();
}
function displayName() {
$sql = 'select first_name, last_name, display_name from users where user_id = "3"';
$results = mysql_query($sql);
$user = mysql_fetch_array($results);
return $user['display_name'];
}
function insertFirstName($name) {
mysql_query("INSERT INTO Persons (first_name)VALUES ('" . $name . "')");
}
?>
// index.php
<?php
require_once 'myFunctions.php';
connectDb();
echo "User known as: " . displayName() . "\n";
insertFirstName("Peter");
closeDb();
?>
But if you insist on using classes:
// User.php
<?php
class User {
private function connectDb() {
mysql_connect('localhost', 'root', 'admin');
mysql_select_db('test');
}
private function closeDb() {
mysql_close();
}
function displayName() {
$this->connectDB();
$sql = 'select first_name, last_name, display_name from users where user_id = "3"';
$results = mysql_query($sql);
$user = mysql_fetch_array($results);
$this->closeDB();
return $user['display_name'];
}
function insertFirstName($name) {
$this->connectDB();
mysql_query("INSERT INTO Persons (first_name)VALUES ('" . $name . "')");
$this->closeDB();
}
}
?>
// index.php
<?php
require_once 'User.php';
$user = new User;
echo "User known as: " . $user->displayName() . "\n";
$user->insertFirstName("Peter");
?>
Actually not bad. abstracted out the db connection and close.
Your sample is not really ideal. Classes should not depend on or modify any external resources, except whatever has been passed to them through arguments / properties / or method calls.

Categories