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{
Related
I learning oop and want to use pdo to execute mysql query. I have a query inside function that I want to execute. When I do this I get an error:
Fatal error: Call to a member function exec() on a non-object
What I'am doing wrong?
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
function testDuplicate($model) {
$SQL = "SELECT product_id FROM " . DB_PREFIX . "product WHERE model LIKE '" .$model . "'";
$result = $conn->exec($SQL);
if ($result->rows) return false;
return true;
}
function testDuplicateCat($cat) {
$SQL = "SELECT category_id FROM " . DB_PREFIX . "category WHERE category_id = '" .$cat . "'";
$result = $conn->exec($SQL);
if ($result->rows) return false;
return true;
}
foreach ($xml->PRODUCT as $child) {
if(testDuplicate($child->ID)){
...
}
}
This issue is raised because the $conn variable inside the testDuplicate function is not defined inside the scope of the function.
You could do this:
function testDuplicate($model) {
global $conn;
...
}
However it is not advice able to do so, its better to use static variables.
function getconn(){
static $conn;
if(!isset($conn)){
$conn = new PDO(...);
}
return $conn;
}
function foobar(){
$result = getconn()->query($sql);
while($row = $result->fetch()){
$ids[] = $row['category_id'];
}
return sizeof($ids) > 0 ? $ids : false;
}
if(($list = foobar()) == false){
echo "products " . var_export($list) . ' are duplicate values';
}
Why? Because you cannot simply overwrite the connection variable, even by accident or by using someone elses code. There are better alternatives but this is just a quick and safe example.
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).
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();
I am very new to programming with PHP and am working on a fun little game to help myself learn. I got some code help from others on pulling a character's stats from the DB but am having trouble getting it to work. I just get "server error" when I try to run it right now. The Database information is fine, and I previously had a working function that pulled from the DB, but wanted to universalize it through a class function. Here is what I have so far.
DB class:
<?php
class db_class
{
//db connection portion
protected $mysqli;
private $db_host = 'XXXXXXX';
private $db_user = 'Filler';
private $db_password = 'Filler';
protected $db_name = 'Filler';
//db connection portion
public function __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
//database connection object
$mysqli = new mysqli($this->db_host, $this->db_user, $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;
}
}
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;
}
}
}
?>
DB class function call:
<?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";
?>
It is difficult to debug this code since I'm used to just putting in breaklines and running through coding errors in things like VBA in compilers, so any debugging tips would be greatly helpful. What am I doing wrong here? Thanks in advance!
You wrote
public __construct($db_host = NULL, ...
but constructors are functions. You need
public function __construct($db_host = NULL, ...
Your db_class constructor accepts four parameters. This instantiation passes none.
$classobject = new db_class();
So you end up with junk in your connection string. Sort that out and you'll be on your way.
You can avoid a lot of debugging by building minimal versions that work. For example, you can write this first.
<?php
class db_class{
public function __construct($db_host = NULL, $db_user = NULL, $db_password = NULL, $db_name = NULL) {
}
}
?>
If that works, check it in to version control, then add a little code to it. (How do you know whether it works? Test it.)
I'm a beginner in OOP PHP.
I'm trying to make a class that will connect,query and fetch data
I done the below coding
class MySQL {
private $set_host;
private $set_username;
private $set_password;
private $set_database;
public function __Construct($set_host, $set_username, $set_password){
$this->host = $set_host;
$this->username = $set_username;
$this->password = $set_password;
$con= mysql_connect($this->host, $this->username, $this->password);
if(!$con){ die("Couldn't connect"); }
}
public function Database($set_database)
{
$this->database=$set_database;
mysql_select_db($this->database)or die("cannot select Dataabase");
}
public function Fetch($set_table_name){
$this->table_name=$set_table_name;
$query=mysql_query("SELECT * FROM ".$this->table_name);
$result= mysql_fetch_array($query);
}
}
$connect = new MySQL('localhost','root','');
$connect->Database('cms');
$connect->Fetch('posts');
what I'm trying to achieve is this
$connect = new MySQL('localhost','root','');
$connect->Database('cms');
$connect->Fetch('posts');
and I want to fetch the data using a format like this
echo $result[0];
but I'm not getting that logic to make this happen
please help
Thanks!
Your Fetch function is only pulling one row from the database, and you aren't returning the results...
The method isn't the best, but in order to achieve what you're trying to do:
public function Fetch($set_table_name){
$query=mysql_query("SELECT * FROM ".$set_table_name);
$result = array();
while ($record = mysql_fetch_array($query)) {
$result[] = $record;
}
return $result;
}
This will make each row a part of $result, but you'll have to access it like this:
You would call the fetch function like this:
$result = $connect->Fetch('posts');
echo $result[0]['columnName']; // for row 0;
Or in a loop:
for ($x = 0; $x < count($result); $x++) {
echo $result[$x][0] . "<BR>"; // outputs the first column from every row
}
That said, fetching the entire result set into memory is not a great idea (some would say it's a very bad idea.)
Edit: It also looks like you have other issues with your class... I have to run but will check back tomorrow and if others haven't set you straight I will expand.
Edit2: Ok, going to do a once-over on your class and try to explain a few things:
class MySQL {
//declaring the private variables that you will access through $this->variable;
private $host;
private $username;
private $password;
private $database;
private $conn; // Adding the connection, more on this later.
public function __Construct($set_host, $set_username, $set_password){
$this->host = $set_host;
$this->username = $set_username;
$this->password = $set_password;
// Combining the connection & connection check using 'or'
// Notice that I removed the semi-colon after the mysql_connect function
$this->conn = mysql_connect($this->host, $this->username, $this->password)
or die("Couldn't connect");
}
public function Database($set_database)
{
$this->database=$set_database;
// Adding the connection to the function allows you to have multiple
// different connections at the same time. Without it, it would use
// the most recent connection.
mysql_select_db($this->database, $this->conn) or die("cannot select Dataabase");
}
public function Fetch($table_name){
// Adding the connection to the function and return the result object instead
return mysql_query("SELECT * FROM ".$table_name, $this->conn);
}
}
$connect = new MySQL('localhost','root','');
$connect->Database('cms');
$posts = $connect->Fetch('posts');
if ($posts && mysql_num_rows($posts) > 0) {
echo "Here is some post data:<BR>";
while ($record = mysql_fetch_array($posts)) {
echo $record[0]; // or a quoted string column name instead of numerical index.
}
} else {
echo "No posts!";
}
I hope this helps... It should get you started at least. If you have more questions you should ask them separately.
That's because $result is set inside the Fetch function. It won't be available outside the Fetch function.
Instead of this line $result= mysql_fetch_array($query);, you'll want something like return mysql_fetch_array($query);.
And then in your code
$row = $connect->Fetch('posts');
// do something with $row
On another note, your Fetch function only applies to database queries that return one row. You'll have to separate the mysql_query & mysql_fetch_array calls into another function if you want to loop through rows in a query result.
And on another note, you shouldn't need to encapsulate this code into a class. PHP already provides OOP-based database classes called PDO, or PHP Data Objects. There's a learning curve to it, but it's best practice, and will help secure your code against things like SQL injection.
This is a pretty good tutorial: http://www.giantflyingsaucer.com/blog/?p=2478
I would make a function that returns the value of the object.
public function returnData($data){
return $this->$data;
}
Then within the page you wish to get the data on just initiate the class and call the function within that class.
$post->returnDate("row name here");
<?php
//database.php
class Databases{
public $con;
public function __construct()
{
$this->con = mysqli_connect("localhost", "root", "", "giit");
if(!$this->con)
{
echo 'Database Connection Error ' . mysqli_connect_error($this->con);
}
}
public function insert($table_name, $data)
{
$string = "INSERT INTO ".$table_name." (";
$string .= implode(",", array_keys($data)) . ') VALUES (';
$string .= "'" . implode("','", array_values($data)) . "')";
if(mysqli_query($this->con, $string))
{
return true;
}
else
{
echo mysqli_error($this->con);
}
}
public function selectmulti($selecttype,$table_name)
{
$array = array();
$query = "SELECT ".$selecttype." FROM ".$table_name."";
$result = mysqli_query($this->con, $query);
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
public function selectsingle($selecttype,$table_name)
{
$query = "SELECT ".$selecttype." FROM ".$table_name."";
$result = mysqli_query($this->con, $query);
$row = mysqli_fetch_assoc($result);
return $row;
}
}
?>
<?php
$data = new Databases;
$post_data = $data->selectmulti('*','centerdetail');
$n = 1;
foreach($post_data as $post)
{
echo $n.'.'.$post['CenterCode'].'___';
$n += 1;
}
echo '<br>';
$post_data = $data->selectsingle('*','centerdetail');
echo $post_data['CenterCode'];
?>